﻿Imports System
Imports System.Reflection
Imports System.Runtime.InteropServices
Imports System.Windows.Forms
Imports System.Diagnostics
Imports System.Xml
Imports System.Xml.XPath
Imports System.Xml.XmlReader
Imports System.Management
Imports System.ServiceProcess
Imports System.IO
Imports System.Configuration
Imports Microsoft.Win32


Public Class clsClientConfiguration

#Region "Balloon tip"
    Private _bBalloon As Boolean = False
    Public Property BalloonTipVisible() As Boolean
        Get
            Return _bBalloon
        End Get
        Set(ByVal value As Boolean)
            _bBalloon = value
        End Set
    End Property
#End Region
    Public Class clsClientConfigs
#Region "Global"
        Public Enum eClient
            CPU = 0
            SXD = 1
            SXM = 2
            SVD = 3
            SVM = 4
            GXA = 5
            GXN = 6
            GVA = 7
            GVN = 8
            Empty = 9
        End Enum
        Private colClients As New Collection
        Public colFreeHWID As New Collection, colTakenHWID As New Collection, colGPUID As New Collection
#End Region
        Public Class sClientSettings
#Region "Global"
            Private colClients As Collection, intGpu As Integer
            Public Sub init()
                colClients = New Collection : intGpu = 0
            End Sub
#End Region
            <Serializable()> _
            Public Class sClient
#Region "Global"
                Public Index As Int16 = -1
                Public ReadOnly Property Client(Optional ByVal CIndex As Int16 = -1) As sClient
                    Get
                        Try
                            If CIndex = -1 And Index = -1 Then
                                Return Nothing
                            ElseIf CIndex = -1 Then
                                If Index > 0 And Index <= Clients.GetUpperBound(0) Then
                                    Return Clients(Index)
                                Else
                                    Return Nothing
                                End If
                            ElseIf Index = -1 Then
                                If CIndex > 0 And CIndex <= Clients.GetUpperBound(0) Then
                                    Return Clients(CIndex)
                                Else
                                    Return Nothing
                                End If
                            End If
                            Return Nothing
                        Catch ex As Exception
                            Return Nothing
                        End Try
                    End Get
                End Property
                Private _EocID As String = ""
                Public Property EocID() As String
                    Get
                        Return _EocID
                    End Get
                    Set(ByVal value As String)
                        _EocID = value
                    End Set
                End Property
#End Region
                <Serializable()> _
                Public Class clsPandeGroup
                    Public Enum eClient
                        CPU = 0
                        SXD = 1
                        SXM = 2
                        SVD = 3
                        SVM = 4
                        GXA = 5
                        GXN = 6
                        GVA = 7
                        GVN = 8
                    End Enum
                    Public ClientType As eClient
                    Private _strUserName As String, _strTeamNumber As String, _strPassKey As String
                    Private _boolProxy As Boolean, _boolProxyPassword As Boolean
                    Private _strProxyHost As String, _strProxyPort As String, _strPUsername As String, _strPPassword As String
                    Private _strAskBeforeNetwork As String
                    Private _boolServiceInstalled As Boolean, _boolAddRemoveService As Boolean, _strUseProxy As String, _strBigWu As String, _strUseProxyPassword As String
                    Private _strCorePriority As String, _strCpuUsage As String
                    Private _strDisableAssembly As String, _strPauseBattery As String
                    Private _strCheckpointInterval As String, _strMemoryIndication As String
                    Private _strAdvancedMethods As String, _strIgnoreDeadline As String
                    Private _strMachineID As String, _strDisableAffinityLock As String
                    Private _strAdditonalParameters As String, _strIPAdress As String
                    Private _intInstalledClient As Int16, _MyClient As clsClientConfiguration.clsClientConfigs.sClientSettings.sClient = Nothing
                    Private _ServiceString As String
                    Public Property ClientIndex() As Int16
                        Get
                            Return _intInstalledClient
                        End Get
                        Set(ByVal value As Int16)
                            _intInstalledClient = value
                        End Set
                    End Property
                    Public Property MyClient() As clsClientConfigs.sClientSettings.sClient
                        Get
                            Try
                                Return _MyClient
                            Catch ex As Exception
                                Return Nothing
                            End Try
                        End Get
                        Set(ByVal value As clsClientConfigs.sClientSettings.sClient)
                            _MyClient = value
                        End Set
                    End Property
                    Public Property ServiceString() As String
                        Get
                            Try
                                Return _ServiceString
                            Catch ex As Exception
                                Return ""
                            End Try
                        End Get
                        Set(ByVal value As String)
                            _ServiceString = value
                        End Set
                    End Property
                    Public Property UserName() As String
                        Get
                            Try
                                Return _strUserName
                            Catch ex As Exception
                                Return "00"
                            End Try
                        End Get
                        Set(ByVal value As String)
                            _strUserName = value
                        End Set
                    End Property
                    Public Property TeamNumber() As String
                        Get
                            Try
                                Return _strTeamNumber
                            Catch ex As Exception
                                Return "00"
                            End Try
                        End Get
                        Set(ByVal value As String)
                            _strTeamNumber = value
                        End Set
                    End Property
                    Public Property PassKey() As String
                        Get
                            Try
                                Return _strPassKey
                            Catch ex As Exception
                                Return "00"
                            End Try
                        End Get
                        Set(ByVal value As String)
                            _strPassKey = value
                        End Set
                    End Property
                    Public Property UseProxy() As String
                        Get
                            Try
                                If _strUseProxy = Nothing Then Return "no"
                                Return _strUseProxy
                            Catch ex As Exception
                                Return "00"
                            End Try
                        End Get
                        Set(ByVal value As String)
                            _strUseProxy = value
                        End Set
                    End Property
                    Public Property UseProxyPassword() As String
                        Get
                            Try
                                If _strUseProxyPassword = Nothing Then Return "no"
                                Return _strUseProxyPassword
                            Catch ex As Exception
                                Return "00"
                            End Try
                        End Get
                        Set(ByVal value As String)
                            _strUseProxyPassword = value
                        End Set
                    End Property
                    Public Property ProxyHost() As String
                        Get
                            Try
                                Return _strProxyHost
                            Catch ex As Exception
                                Return "00"
                            End Try
                        End Get
                        Set(ByVal value As String)
                            _strProxyHost = value
                        End Set
                    End Property
                    Public Property ProxyPort() As String
                        Get
                            Try
                                Return _strProxyPort
                            Catch ex As Exception
                                Return "00"
                            End Try
                        End Get
                        Set(ByVal value As String)
                            _strProxyPort = value
                        End Set
                    End Property
                    Public Property ProxyUserName() As String
                        Get
                            Try
                                Return _strPUsername
                            Catch ex As Exception
                                Return "00"
                            End Try
                        End Get
                        Set(ByVal value As String)
                            _strPUsername = value
                        End Set
                    End Property
                    Public Property ProxyPassword() As String
                        Get
                            Try
                                Return _strPPassword
                            Catch ex As Exception
                                Return "00"
                            End Try
                        End Get
                        Set(ByVal value As String)
                            _strPPassword = value
                        End Set
                    End Property
                    Public ReadOnly Property ServiceName() As String
                        Get
                            Dim sName As String = "Folding@Home-"
                            If ClientType < 5 And ClientType <> eClient.CPU Then
                                sName = sName & "GPU-[" & MachineID & "]"
                            ElseIf ClientType >= 5 Then
                                sName = sName & "CPU-[" & MachineID & "]"
                            ElseIf ClientType = eClient.CPU Then
                                sName = sName & "CPU-[" & MachineID & "]"
                            End If
                            Return sName.ToUpper
                        End Get
                    End Property
                    Public ReadOnly Property ServiceMode() As Boolean 'To determine gui display options
                        Get
                            Try
                                Dim sString As String
                                If ClientType < 5 Then
                                    sString = "Folding@Home-CPU-[" & MachineID & "]"
                                Else
                                    sString = "Folding@Home-GPU-[" & MachineID & "]"
                                End If
                                Dim rKey As RegistryKey = Registry.LocalMachine.OpenSubKey("SYSTEM\CurrentControlSet\Services")
                                Dim sVal() As String = rKey.GetSubKeyNames
                                For Each sSer As String In sVal
                                    If sSer.ToUpper = sString.ToUpper Then
                                        Return True
                                    End If
                                Next
                                Return False
                            Catch ex As Exception
                                Debug.Print(ex.Message)
                                Return Nothing
                            End Try
                        End Get
                    End Property
                   
                    Public Property IsService(Optional ByVal Extended As Boolean = False) As Boolean
                        Get
                            Try
                                If Extended Then
                                    Dim sName As String = ("Folding@Home-" & ServiceName).ToUpper
                                    Dim rKey As RegistryKey = Registry.LocalMachine.OpenSubKey("SYSTEM\CurrentControlSet\Services\", False)
                                    If rKey.SubKeyCount = Nothing Or rKey.Name = Nothing Then Return False
                                    For Each SService As ServiceProcess.ServiceController In ServiceProcess.ServiceController.GetServices()
                                        If SService.DisplayName.ToUpper = sName Or SService.ServiceName.ToUpper = sName Then
                                            _boolServiceInstalled = True
                                            Return (True)
                                        End If
                                    Next
                                    _boolServiceInstalled = False
                                    Return False
                                End If
                                If _boolServiceInstalled = Nothing Then Return False
                                Return _boolServiceInstalled
                            Catch ex As Exception
                                Return False
                            End Try
                        End Get
                        Set(ByVal value As Boolean)
                            _boolServiceInstalled = value
                        End Set
                    End Property
                    Public ReadOnly Property HasServiceError() As Boolean
                        Get
                            Return (IsService(True).ToString.ToUpper <> ServiceString.ToUpper)
                        End Get
                    End Property
                    Public Property AddRemoveService() As String
                        Get
                            Try
                                If _boolAddRemoveService = Nothing Then Return "no"
                                If _boolAddRemoveService Then
                                    Return "yes"
                                Else
                                    Return "no"
                                End If
                            Catch ex As Exception
                                Return "00"
                            End Try
                        End Get
                        Set(ByVal value As String)
                            If value = "yes" Then
                                _boolAddRemoveService = True
                            ElseIf value = "no" Then
                                _boolAddRemoveService = False
                            End If
                        End Set
                    End Property
                    Public Property AcceptedWUSize() As String
                        Get
                            Try
                                If _strBigWu = Nothing Then Return "normal"
                                Return _strBigWu
                            Catch ex As Exception
                                Return "normal"
                            End Try
                        End Get
                        Set(ByVal value As String)
                            _strBigWu = value
                        End Set
                    End Property
                    Public Property CorePriority() As String
                        Get
                            Try
                                If _strCorePriority = Nothing Then Return "idle"
                                Return _strCorePriority
                            Catch ex As Exception
                                Return "00"
                            End Try
                        End Get
                        Set(ByVal value As String)
                            _strCorePriority = value
                        End Set
                    End Property
                    Public Property CpuUsage() As String
                        Get
                            Try
                                If _strCpuUsage = Nothing Then Return "100"
                                Return _strCpuUsage
                            Catch ex As Exception
                                Return "00"
                            End Try
                        End Get
                        Set(ByVal value As String)
                            _strCpuUsage = value
                        End Set
                    End Property
                    Public Property DisableAssembly() As String
                        Get
                            Try
                                If _strDisableAssembly = Nothing Then Return "no"
                                Return _strDisableAssembly
                            Catch ex As Exception
                                Return "00"
                            End Try
                        End Get
                        Set(ByVal value As String)
                            _strDisableAssembly = value
                        End Set
                    End Property
                    Public Property PauseBattery() As String
                        Get
                            Try
                                If _strPauseBattery = Nothing Then Return "no"
                                Return _strPauseBattery
                            Catch ex As Exception
                                Return "00"
                            End Try
                        End Get
                        Set(ByVal value As String)
                            _strPauseBattery = value
                        End Set
                    End Property
                    Public Property CheckpointInterval() As String
                        Get
                            Try
                                If _strCheckpointInterval = Nothing Then Return "15"
                                Return _strCheckpointInterval
                            Catch ex As Exception
                                Return "00"
                            End Try
                        End Get
                        Set(ByVal value As String)
                            _strCheckpointInterval = value
                        End Set
                    End Property
                    Public Property MemoryUsage() As String
                        Get
                            Try
                                If _strMemoryIndication = Nothing Then Return (My.Computer.Info.TotalPhysicalMemory / 1024 / 1024).ToString
                                Return _strMemoryIndication
                            Catch ex As Exception
                                Return "00"
                            End Try
                        End Get
                        Set(ByVal value As String)
                            _strMemoryIndication = value
                        End Set
                    End Property
                    Public Property ForceAdvMethods() As String
                        Get
                            Try
                                If _strAdvancedMethods = Nothing Then Return "no"
                                Return _strAdvancedMethods
                            Catch ex As Exception
                                Return "00"
                            End Try
                        End Get
                        Set(ByVal value As String)
                            _strAdvancedMethods = value
                        End Set
                    End Property
                    Public Property IgnoreDeadline() As String
                        Get
                            Try
                                If _strIgnoreDeadline = Nothing Then Return "no"
                                Return _strIgnoreDeadline
                            Catch ex As Exception
                                Return "00"
                            End Try
                        End Get
                        Set(ByVal value As String)
                            _strIgnoreDeadline = value
                        End Set
                    End Property
                    Public Property MachineID() As String
                        Get
                            Try
                                If _strMachineID = Nothing Then Return "0"
                                Return _strMachineID
                            Catch ex As Exception
                                Return "00"
                            End Try
                        End Get
                        Set(ByVal value As String)
                            _strMachineID = value
                        End Set
                    End Property
                    Public Property DisableAffinitylock() As String
                        Get
                            Try
                                If _strDisableAffinityLock = Nothing Then Return "no"
                                Return _strDisableAffinityLock
                            Catch ex As Exception
                                Return "00"
                            End Try
                        End Get
                        Set(ByVal value As String)
                            _strDisableAffinityLock = value
                        End Set
                    End Property
                    Public Property AdditionalParameters() As String
                        Get
                            Try
                                If _strAdditonalParameters = Nothing Then Return ""
                                Return _strAdditonalParameters
                            Catch ex As Exception
                                Return "00"
                            End Try
                        End Get
                        Set(ByVal value As String)
                            _strAdditonalParameters = value
                        End Set
                    End Property
                    Public Property IPAdress() As String
                        Get
                            Try
                                If _strIPAdress = Nothing Then Return ""
                                Return _strIPAdress
                            Catch ex As Exception
                                Return "00"
                            End Try
                        End Get
                        Set(ByVal value As String)
                            _strIPAdress = value
                        End Set
                    End Property
                    Public Property AskNetwork() As String
                        Get
                            Try
                                If _strAskBeforeNetwork = Nothing Then Return "no"
                                Return _strAskBeforeNetwork
                            Catch ex As Exception
                                Return "00"
                            End Try
                        End Get
                        Set(ByVal value As String)
                            _strAskBeforeNetwork = value
                        End Set
                    End Property
                End Class

                Public Class clsGUIController
#Region "Standard"
                    Public Enum eClient
                        CPU = 0
                        SXD = 1
                        SXM = 2
                        SVD = 3
                        SVM = 4
                        GXA = 5
                        GXN = 6
                        GVA = 7
                        GVN = 8
                        Empty = 9
                    End Enum
                    Private _tClient As eClient
                    Private _MyClient As clsClientConfigs.sClientSettings.sClient
                    Private _Ordinal As Int16
                    Private _strClientLocation As String, _strClientExe As String, _strCProject As String
                    Private _StrClientVersion As String, _ClientFAQ As String, _ClientGUIDE As String
                    Public Property Ordinal() As Int16
                        Get
                            Return _Ordinal
                        End Get
                        Set(ByVal value As Int16)
                            _Ordinal = value
                        End Set
                    End Property
                    Public Property MyClient() As clsClientConfigs.sClientSettings.sClient
                        Get
                            Return _MyClient
                        End Get
                        Set(ByVal value As clsClientConfigs.sClientSettings.sClient)
                            _MyClient = value
                        End Set
                    End Property
                    Public Property TypeOfClient() As eClient
                        Set(ByVal Value As eClient)
                            _tClient = Value
                        End Set
                        Get
                            Return _tClient
                        End Get
                    End Property

                    Public Property ClientLocation() As String
                        Get
                            Return _strClientLocation
                        End Get
                        Set(ByVal value As String)
                            _strClientLocation = value
                            _Queue = New clsQueue(value)
                        End Set
                    End Property
                    Public Property ClientEXE() As String
                        Get
                            Return _strClientExe
                        End Get
                        Set(ByVal value As String)
                            _strClientExe = value
                        End Set
                    End Property
                    Public ReadOnly Property ShortName() As String
                        Get
                            Dim strP As String = Mid(ClientEXE, Len(cPath) + 2)
                            Return Mid(strP, 1, strP.IndexOf("\"))
                        End Get
                    End Property
                    Public Property ClientVersion() As String
                        Get
                            Return _StrClientVersion
                        End Get
                        Set(ByVal value As String)
                            _StrClientVersion = value
                        End Set
                    End Property
#End Region

#Region "Priority and affinity settings"
                    Private _strPriority(0 To 0) As String
                    Private _strAffinity(0 To 0) As String
                    Private _intAP_count As Int16 = 0
                    Private _fahWorkers() As Process

                    Public Function GetWorkers() As Boolean
                        Dim intIndex As Int16 = 0
                        Try
                            Dim wString As String = ClientLocation & "\FahCore_" & _Queue.ActiveSlot.CoreNumber & ".exe"
                            ReDim _fahWorkers(0 To 0)
Fill:
                            Dim pcTest() As Process = Process.GetProcessesByName("FahCore_" & Queue.ActiveSlot.CoreNumber.ToUpper)
                            If pcTest.GetUpperBound(0) < intIndex Then Return False
                            For xInt As Int16 = intIndex To pcTest.GetUpperBound(0)
                                If pcTest(xInt).MainModule.FileName.ToUpper = wString.ToUpper Then
                                    ReDim Preserve _fahWorkers(0 To _fahWorkers.GetUpperBound(0) + 1)
                                    _fahWorkers(_fahWorkers.GetUpperBound(0)) = pcTest(xInt)
                                End If
                            Next
                            Return (_fahWorkers.GetUpperBound(0) > 0)
                        Catch W32 As System.ComponentModel.Win32Exception 'Enum fails for consequitive calls since this code run in seperate threads
                            intIndex += 1
                            GoTo Fill
                        Catch ex As Exception
                            Return False
                        End Try
                    End Function

                    Public Function ApplyAP() As Boolean
                        Try
                            If Not GetWorkers() Then Return False
                            If APcount < 1 Then Return False
                            For xInt As Int16 = 1 To APcount
                                _fahWorkers(xInt).PriorityClass = Me.intPrioritySettings(xInt)
                                _fahWorkers(xInt).ProcessorAffinity = intPtrAffinty(xInt)
                            Next
                            Return True
                        Catch ex As Exception
                            Return False
                        End Try
                    End Function

                    Public ReadOnly Property WorkerName() As String
                        Get
                            Return "FahCore_" & _Queue.ActiveSlot.CoreNumber & ".exe"
                        End Get
                    End Property

                    Public ReadOnly Property WorkerCount() As Int16
                        Get
                            Try
                                Return _fahWorkers.GetUpperBound(0)
                            Catch ex As Exception
                                Return 0
                            End Try

                        End Get
                    End Property

                    Public Property WorkerPriority(ByVal Index As Int16) As ProcessPriorityClass
                        Get
                            Return _fahWorkers(Index).PriorityClass
                        End Get
                        Set(ByVal value As ProcessPriorityClass)
                            _fahWorkers(Index).PriorityClass = value
                        End Set
                    End Property

                    Public Property WorkerAffinity(ByVal Index As Int16) As IntPtr
                        Get
                            Return _fahWorkers(Index).ProcessorAffinity
                        End Get
                        Set(ByVal value As IntPtr)
                            _fahWorkers(Index).ProcessorAffinity = value
                        End Set
                    End Property

                    Public ReadOnly Property APcount() As Int16
                        Get
                            Return _strPriority.GetUpperBound(0)
                            'Return _intAP_count
                        End Get
                    End Property

                    Public Property AffintySettings(ByVal wIndex As Short) As String
                        Get
                            Try
                                Return _strAffinity(wIndex)
                            Catch ex As Exception
                                Return ""
                            End Try
                        End Get
                        Set(ByVal value As String)
                            Try
                                If _strAffinity.GetUpperBound(0) < wIndex Then
                                    ReDim Preserve _strAffinity(0 To wIndex)
                                    _strAffinity(wIndex) = value
                                Else
                                    _strAffinity(wIndex) = value
                                End If
                            Catch ex As Exception
                                ReDim Preserve _strAffinity(0 To wIndex)
                                _strAffinity(wIndex) = value
                            End Try
                        End Set
                    End Property

                    Public ReadOnly Property intPtrAffinty(ByVal wIndex) As IntPtr
                        Get
                            Dim strB As String = AffintySettings(wIndex)
                            Dim strA As String = ""
                            For xInt As Int16 = strB.Length To 1 Step -1
                                strA &= Mid(strB, xInt, 1)
                            Next
                            Return Convert.ToInt32(strA, 2)
                        End Get
                    End Property

                    Public Property PrioritySettings(ByVal wIndex As Short) As String
                        Get
                            Try
                                Return _strPriority(wIndex)
                            Catch ex As Exception
                                Return ""
                            End Try
                        End Get
                        Set(ByVal value As String)
                            Try
                                If _strAffinity.GetUpperBound(0) < wIndex Then
                                    ReDim Preserve _strPriority(0 To wIndex)
                                    _strPriority(wIndex) = value
                                Else
                                    _strPriority(wIndex) = value
                                End If
                            Catch ex As Exception
                                ReDim Preserve _strPriority(0 To wIndex)
                                _strPriority(wIndex) = value
                            End Try
                        End Set
                    End Property

                    Public ReadOnly Property intPrioritySettings(ByVal wIndex As Short) As ProcessPriorityClass
                        Get
                            Try
                                Select Case PrioritySettings(wIndex)
                                    Case Is = ProcessPriorityClass.RealTime.ToString
                                        Return ProcessPriorityClass.RealTime
                                    Case Is = ProcessPriorityClass.High.ToString
                                        Return ProcessPriorityClass.High
                                    Case Is = ProcessPriorityClass.AboveNormal.ToString
                                        Return ProcessPriorityClass.AboveNormal
                                    Case Is = ProcessPriorityClass.Normal.ToString
                                        Return ProcessPriorityClass.Normal
                                    Case Is = ProcessPriorityClass.BelowNormal.ToString
                                        Return ProcessPriorityClass.BelowNormal
                                    Case Is = ProcessPriorityClass.Idle.ToString
                                        Return ProcessPriorityClass.Idle
                                    Case Is = "low"
                                        Return ProcessPriorityClass.BelowNormal
                                    Case Is = "idle"
                                        Return ProcessPriorityClass.Idle
                                End Select
                            Catch ex As Exception
                                Return -1
                            End Try
                        End Get
                    End Property
#End Region

#Region "Dll imports"
                    <DllImport("kernel32.dll", SetLastError:=True)> _
                   Private Shared Function GetConsoleWindow() As IntPtr
                    End Function
                    <DllImport("kernel32.dll", SetLastError:=True)> _
                    Private Shared Function AttachConsole(ByVal procid As Integer) As Boolean
                    End Function
                    <DllImport("kernel32.dll", SetLastError:=True)> _
                    Private Shared Function FreeConsole() As Boolean
                    End Function
                    <DllImport("user32.dll")> _
                    Private Shared Function SetForegroundWindow(ByVal hWnd As IntPtr) As Boolean
                    End Function
                    <DllImport("user32.dll")> _
                    Private Shared Function GetForegroundWindow() As Long
                    End Function
                    <DllImport("kernel32.dll", SetLastError:=True)> _
                    Private Shared Function GenerateConsoleCtrlEvent(ByVal ctrlEvent As Integer, ByVal procid As Integer) As Boolean
                    End Function
                    <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
                    Private Shared Function ShowWindow(ByVal hWnd As IntPtr, ByVal nCmdShow As Int32) As Boolean
                    End Function
                    Declare Auto Function OpenProcess Lib "kernel32.dll" (ByVal dwDesiredAccess As PROCESS_ACCESS, ByVal bInheritHandle As Boolean, ByVal dwProcessId As Long) As IntPtr
                    <Flags()> _
                    Public Enum PROCESS_ACCESS As Integer
                        ' Specifies all possible access flags for the process object.
                        PROCESS_ALL_ACCESS = &H1F0FFF
                        ' Enables using the process handle in the CreateRemoteThread function
                        ' to create a thread in the process.
                        PROCESS_CREATE_THREAD = &H2
                        ' Enables using the process handle as either the source or
                        ' target process in the DuplicateHandle function to duplicate a handle.
                        PROCESS_DUP_HANDLE = &H40
                        ' Enables using the process handle in the GetExitCodeProcess and
                        ' GetPriorityClass functions to read information from the process object.
                        PROCESS_QUERY_INFORMATION = &H400
                        ' Enables using the process handle in the SetPriorityClass function to
                        ' set the priority class of the process.
                        PROCESS_SET_INFORMATION = &H200
                        ' Enables using the process handle in the TerminateProcess function to
                        ' terminate the process.
                        PROCESS_TERMINATE = &H1
                        ' Enables using the process handle in the VirtualProtectEx and
                        ' WriteProcessMemory functions to modify the virtual memory of the process.
                        PROCESS_VM_OPERATION = &H8
                        ' Enables using the process handle in the ReadProcessMemory function to
                        ' read from the virtual memory of the process.
                        PROCESS_VM_READ = &H10
                        ' Enables using the process handle in the WriteProcessMemory function to
                        ' write to the virtual memory of the process.
                        PROCESS_VM_WRITE = &H20
                        ' Enables using the process handle in any of the wait functions to wait
                        ' for the process to terminate.
                        SYNCHRONIZE = &H100000
                    End Enum
                    <DllImport("kernel32.dll", SetLastError:=True)> _
                    Public Shared Function ReadProcessMemory(ByVal hProcess As IntPtr, ByVal lpBaseAddress As IntPtr, <Out()> ByVal lpBuffer() As Byte, ByVal dwSize As Integer, ByRef lpNumberOfBytesRead As Integer) As Boolean
                    End Function
                    <DllImport("kernel32.dll", SetLastError:=True)> _
                    Public Shared Function ReadProcessMemory(ByVal hProcess As IntPtr, ByVal lpBaseAddress As IntPtr, <Out(), MarshalAs(UnmanagedType.AsAny)> ByVal lpBuffer As Object, ByVal dwSize As Integer, ByRef lpNumberOfBytesRead As Integer) As Boolean
                    End Function
                    <DllImport("kernel32.dll", SetLastError:=True)> _
                    Public Shared Function ReadProcessMemory(ByVal hProcess As IntPtr, ByVal lpBaseAddress As IntPtr, ByVal lpBuffer As IntPtr, ByVal iSize As Integer, ByRef lpNumberOfBytesRead As Integer) As Boolean
                    End Function
                    <DllImport("NTDLL.dll", SetLastError:=True)> _
                    Public Shared Function NtQueryInformationProcess(ByVal processHandle As IntPtr, ByVal processInformationClass As Integer, ByVal processInformation As IntPtr, ByVal processInformationLength As Integer, ByVal returnLength As IntPtr) As Integer
                    End Function

#End Region

#Region "Client control"
                    Public Const SW_HIDE As Integer = 0
                    Public Const SW_SHOWNORMAL As Integer = 1
                    Public Const SW_SHOWMINIMIZED As Integer = 2
                    Public Const SW_SHOWMAXIMIZED As Integer = 3
                    Public Const SW_SHOWNOACTIVATE As Integer = 4
                    Public Const SW_RESTORE As Integer = 9
                    Public Const SW_SHOWDEFAULT As Integer = 10
                    Public Const CTRL_C_EVENT As Integer = 0

                    Private Delegate Sub eHandler()
                    Delegate Sub uIcon(ByVal Ics As iState)

                    Private WithEvents _Nicon As New NotifyIcon
                    Private WithEvents _cProc As New Process
                    Private WithEvents cMenu As New ContextMenuStrip
                    Private _sCont As New ServiceController
                    Private _Service As Boolean = False
                    Private _Running As Boolean = False
                    Private _bWaitFrame As Boolean = False
                    Private _bWaitUnit As Boolean = False
                    Private __bWaitFrame As Boolean = False
                    Public Property CloseWhenFrameCompletes() As Boolean
                        Get
                            Return _bWaitFrame
                        End Get
                        Set(ByVal value As Boolean)
                            _bWaitFrame = value
                        End Set
                    End Property
                    Public Property CloseWhenUnitCompletes() As Boolean
                        Get
                            Return _bWaitUnit
                        End Get
                        Set(ByVal value As Boolean)
                            _bWaitUnit = value
                            If _bWaitUnit And Queue.Progress < 99 Then _bWaitFrame = True
                        End Set
                    End Property

                    Public Enum eWindowState
                        Err = -1
                        Service = 0
                        Visible = 1
                        Hidden = 2
                    End Enum
                    Public Enum eServiceState
                        Err = 0
                        Running = 1
                        Paused = 2
                        Stopped = 3
                    End Enum

                    Public Enum iState
                        Err = 0
                        iStop = 1
                        iRun = 2
                        iPause = 3
                    End Enum

                    Public Property cProcess() As Process
                        Get
                            Try
                                If _cProc.ExitCode <> 0 Then Return _cProc
                            Catch ex As Exception
                                Return Nothing
                            End Try
                            Return _cProc
                        End Get
                        Set(ByVal value As Process)
                            _cProc = value
                            AddHandler _cProc.Exited, AddressOf ExitHandler
                        End Set
                    End Property

                    Public Property sController() As ServiceController
                        Get
                            Try
                                If _sCont.ServiceName = MyClient.PandeGroup.ServiceName Then
                                    Return _sCont
                                Else
                                    'Log to window
                                    Return Nothing
                                End If
                            Catch ex As Exception
                                'Log to window
                                Return Nothing
                            End Try
                        End Get
                        Set(ByVal value As ServiceController)
                            _sCont = value
                        End Set
                    End Property

                    Public Property Running(Optional ByVal Extended As Boolean = False) As Boolean
                        Get
                            If Extended Then
                                'Check by process
                                Try
                                    If _cProc.HasExited Then
                                        _Running = False
                                        Return False
                                    Else
                                        _Running = True
                                        Return True
                                    End If
                                Catch ex As Exception
                                    _Running = False
                                    Return False
                                End Try
                            Else
                                Return _Running
                            End If
                        End Get
                        Set(ByVal value As Boolean)
                            _Running = value
                        End Set
                    End Property

                    Public Property IsService() As Boolean
                        Get
                            Return _Service
                        End Get
                        Set(ByVal value As Boolean)
                            _Service = value
                        End Set
                    End Property

                    Public ReadOnly Property wState() As eWindowState
                        Get
                            Try
                                If MyClient.PandeGroup.ServiceMode Then Return eWindowState.Service
                                _cProc = Process.GetProcessById(_cProc.Id)
                                If _cProc.MainWindowHandle <> 0 Then
                                    Return eWindowState.Visible
                                Else
                                    Return eWindowState.Hidden
                                End If
                            Catch ex As Exception
                                Return eWindowState.Err
                            End Try
                        End Get
                    End Property

                    Public ReadOnly Property ServiceState() As eServiceState
                        Get
                            Try
                                If _sCont.DisplayName.ToUpper = MyClient.PandeGroup.ServiceName Or _sCont.ServiceName.ToUpper = MyClient.PandeGroup.ServiceName Then
ReturnThis:
                                    With _sCont
                                        If .Status = ServiceControllerStatus.ContinuePending Then
                                            .WaitForStatus(ServiceControllerStatus.Running, TimeSpan.FromSeconds(10))
                                        ElseIf .Status = ServiceControllerStatus.PausePending Then
                                            .WaitForStatus(ServiceControllerStatus.Paused, TimeSpan.FromSeconds(10))
                                        ElseIf .Status = ServiceControllerStatus.StartPending Then
                                            .WaitForStatus(ServiceControllerStatus.Running, TimeSpan.FromSeconds(10))
                                        ElseIf .Status = ServiceControllerStatus.StopPending Then
                                            .WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(10))
                                        ElseIf .Status = ServiceControllerStatus.Running Then
IsRunning:
                                            Return eServiceState.Running
                                        ElseIf .Status = ServiceControllerStatus.Paused Then
IsPaused:
                                            Return eServiceState.Paused
                                        ElseIf .Status = ServiceControllerStatus.Stopped Then
IsStopped:
                                            Return eServiceState.Stopped
                                        End If
                                    End With
                                Else
                                    If AttachToSC() Then GoTo ReturnThis
                                    Return eServiceState.Err
                                End If
                            Catch ex As Exception
                                'Log to window
                                Return eServiceState.Err
                            End Try
                        End Get
                    End Property

                    Public Function AttachToSC() As Boolean
                        _sCont = New ServiceController
                        For Each SService As ServiceProcess.ServiceController In ServiceProcess.ServiceController.GetServices()
                            If SService.DisplayName.ToUpper = MyClient.PandeGroup.ServiceName Or SService.ServiceName.ToUpper = MyClient.PandeGroup.ServiceName Then
                                _sCont = SService
                            End If
                        Next
                        Try
                            If Not _sCont.DisplayName = MyClient.PandeGroup.ServiceName Then
                                'Log to window
                                Return False
                            Else
                                Return True
                            End If
                        Catch ex As Exception
                            'Log to window
                            Return False
                        End Try
                    End Function

                    Public Function StartClient(Optional ByVal Arguments As String = "", Optional ByVal NoUpdate As Boolean = False) As Boolean
                        Try
                            If MyClient.PandeGroup.ServiceMode Then
                                If Not AttachToSC() Then
                                    'Log to window 
                                    Return False
                                End If
                                If _sCont.Status = ServiceControllerStatus.Running Or _sCont.Status = ServiceControllerStatus.StartPending Then
                                    'Log to window
                                    Return True
                                End If
                                With _sCont
                                    Select Case .Status
                                        Case ServiceControllerStatus.StopPending
                                            .WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(10))
                                            If .Status = ServiceControllerStatus.Stopped Then GoTo IsStopped
                                            'Log to window stop pending
                                            Return False
                                        Case ServiceControllerStatus.Stopped
IsStopped:
                                            'Log to window starting service
                                            .Start()
                                            .WaitForStatus(ServiceControllerStatus.Running, TimeSpan.FromSeconds(10))
                                            If .Status = ServiceControllerStatus.Running Then
                                                GoTo UpdateProcess
                                            End If
                                        Case ServiceControllerStatus.PausePending
                                            .WaitForStatus(ServiceControllerStatus.Paused, TimeSpan.FromSeconds(10))
                                            If .Status = ServiceControllerStatus.Paused Then GoTo Paused
                                            'Log to window pause pending
                                            Return False
                                        Case ServiceControllerStatus.Paused
Paused:
                                            'Log to window resuming paused service
                                            .Continue()
                                            .WaitForStatus(ServiceControllerStatus.Running, TimeSpan.FromSeconds(10))
                                            If .Status = ServiceControllerStatus.Running Then
                                                GoTo UpdateProcess
                                            End If
                                        Case ServiceControllerStatus.StartPending
                                            .WaitForStatus(ServiceControllerStatus.Running, TimeSpan.FromSeconds(10))
                                            If .Status = ServiceControllerStatus.Running Then GoTo IsRunning
                                        Case ServiceControllerStatus.ContinuePending
                                            .WaitForStatus(ServiceControllerStatus.Running, TimeSpan.FromSeconds(10))
                                            If .Status = ServiceControllerStatus.Running Then GoTo IsRunning
                                        Case ServiceControllerStatus.Running
IsRunning:
                                            'Log to window service was running
                                            GoTo UpdateProcess
                                    End Select
                                End With
UpdateProcess:
                                'update _proc with client process
                                If Not NoUpdate Then StartUpdate(True)
                                If mySettings.bAutoReload Then StartWatching()
                                Return True
                            Else
                                If Running(True) Then Return True
                                RemoveHandler _cProc.Exited, Nothing
                                _cProc = New Process
                                If mySettings.bStartConsolesHidden Then
                                    With _cProc.StartInfo
                                        .FileName = ClientEXE
                                        .WorkingDirectory = Mid(ClientEXE, 1, ClientEXE.LastIndexOf("\"))
                                        .WindowStyle = ProcessWindowStyle.Hidden
                                        .Arguments = Arguments
                                    End With
                                Else
                                    With _cProc.StartInfo
                                        .FileName = ClientEXE
                                        .WorkingDirectory = Mid(ClientEXE, 1, ClientEXE.LastIndexOf("\"))
                                        .Arguments = Arguments
                                    End With
                                End If
                                _cProc.Start() ' wait for main window to be created?!
                                AddHandler _cProc.Exited, AddressOf ExitHandler
                                WaitMS(500)
                                If Not NoUpdate Then StartUpdate(True)
                                If mySettings.bAutoReload Then StartWatching()
                                Return True
                            End If
                        Catch ex As Exception
                            Return False
                        End Try
                    End Function

                    Public Function PauseClient() As Boolean
                        Try
                            If Not AttachToSC() Then
                                'Log to window
                                Return False
                            ElseIf Not _sCont.Status = ServiceControllerStatus.Running Then
                                'Log to window
                                Return False
                            ElseIf Not _sCont.CanPauseAndContinue Then
                                'Log to window
                                Return False
                            Else
                                _sCont.Pause()
                                _sCont.WaitForStatus(ServiceControllerStatus.Paused, TimeSpan.FromSeconds(10))
                                StartUpdate(True)
                                If mySettings.bAutoReload Then StartWatching()
                                Return True
                            End If
                        Catch ex As Exception
                            'log to window
                            Return False
                        End Try
                    End Function

                    Public Function ContinueClient() As Boolean
                        Try
                            If Not AttachToSC() Then
                                'Log to window
                                Return False
                            ElseIf _sCont.Status <> ServiceControllerStatus.Paused Then
                                'Log to window 
                                Return False
                            Else
                                _sCont.Continue()
                                _sCont.WaitForStatus(ServiceControllerStatus.Running, TimeSpan.FromSeconds(10))
                                StartUpdate(True)
                                If mySettings.bAutoReload Then StartWatching()
                                Return True
                            End If
                        Catch ex As Exception
                            'Log to window 
                            Return False
                        End Try
                    End Function

                    Public Function StopClient() As Boolean
                        Try
                            If MyClient.PandeGroup.ServiceMode Then
                                AttachToSC()
                                If _sCont.Status = ServiceControllerStatus.Stopped Or _sCont.Status = ServiceControllerStatus.StopPending Then GoTo CloseConsole
                                Try
                                    _sCont.Stop()
                                    Dim dNow As DateTime = DateTime.Now
                                    _sCont.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(5))
                                    If _sCont.Status = ServiceControllerStatus.Stopped Then
                                        StopWatching()
                                        StartUpdate(True)
                                        Return True
                                    Else
                                        Return False
                                    End If
                                Catch ex As Exception
                                    'Log to window
                                    Return False
                                End Try
                            Else
CloseConsole:
                                Try
                                    'old
                                    If _cProc.HasExited Then Return True
                                    If _cProc.MainWindowHandle = 0 Then
                                        If ShowConsole() Then
                                            GoTo CloseClient
                                        Else
                                            'log to window
                                            Return False
                                        End If
                                    Else
CloseClient:
                                        Dim dE As DateTime = DateTime.Now.AddSeconds(5)
                                        Do
                                            SetForegroundWindow(_cProc.MainWindowHandle)
                                            WaitMS(5)
                                            If GetForegroundWindow() = _cProc.MainWindowHandle Then
                                                Dim sK As SendKeys
                                                sK.Send("^C")
                                            Else
                                                If _cProc.HasExited Then
                                                    Exit Do
                                                Else
                                                    If DateTime.Now > dE Then
                                                        'Log to window
                                                        Return False
                                                    End If
                                                    SetForegroundWindow(_cProc.MainWindowHandle)
                                                    WaitMS(5)
                                                End If
                                            End If
                                        Loop
                                        StopWatching()
                                        StartUpdate(True)
                                        Return True
                                    End If
                                Catch ex As Exception
                                    'Log to window
                                    Return False
                                End Try
                            End If
                            Return True
                        Catch ex As Exception
                            'Log to window
                            Return False
                        End Try
                    End Function

                    Public Function ShowConsole() As Boolean
                        Try
                            Dim ok As Boolean = AttachConsole(_cProc.Id)
                            If ok Then
                                Dim hd1 As IntPtr = GetConsoleWindow()
                                ShowWindow(hd1, SW_RESTORE)
                                FreeConsole()
                            End If
                            _cProc = Process.GetProcessById(_cProc.Id)
                            StartUpdate(True)
                            Return True
                        Catch ex As Exception
                            Return False
                        End Try
                    End Function

                    Public Function HideConsole() As Boolean
                        Try
                            Dim ok As Boolean = AttachConsole(_cProc.Id)
                            If ok Then
                                Dim hd1 As IntPtr = GetConsoleWindow()
                                ShowWindow(hd1, SW_HIDE)
                                FreeConsole()
                            End If
                            _cProc = Process.GetProcessById(_cProc.Id)
                            StartUpdate(True)
                            Return True
                        Catch ex As Exception
                            Return False
                        End Try
                    End Function

                    Public Sub ShowIcon(ByVal icS As iState)
                        'old
                        Try
                            If cMenu.InvokeRequired Then
                                Dim nInv As New uIcon(AddressOf UpdateIconInv)
                                cMenu.Invoke(nInv, New Object() {icS})
                            Else
                                cMenu.Items.Clear()
                                If MyClient.PandeGroup.ServiceMode Then
                                    Select Case icS
                                        Case iState.Err
                                            _Nicon.Icon = My.Resources.fold_log_Warning
                                            'Add more code!  
                                            cMenu.Items.Add("View error")
                                        Case iState.iStop
                                            cMenu.Items.Add("Start")
                                            _Nicon.Icon = My.Resources.Icon_stop
                                        Case iState.iRun
                                            _Nicon.Icon = My.Resources.Icon_start
                                            cMenu.Items.Add("Stop")
                                            cMenu.Items.Add("Pause")
                                        Case iState.iPause
                                            _Nicon.Icon = My.Resources.Icon_stop 'No pause icon?
                                            cMenu.Items.Add("Continue")
                                            cMenu.Items.Add("Stop")
                                        Case iState.iPause
                                    End Select
                                Else
                                    Select Case icS
                                        Case iState.Err
                                            _Nicon.Icon = My.Resources.fold_log_Warning
                                            'Add more code!  
                                            cMenu.Items.Add("View error")
                                        Case iState.iRun
                                            _Nicon.Icon = My.Resources.Icon_start
                                            cMenu.Items.Add("Stop")
                                        Case iState.iStop
                                            cMenu.Items.Add("Start")
                                            _Nicon.Icon = My.Resources.Icon_stop
                                    End Select
                                End If
                                If wState = eWindowState.Visible Then
                                    cMenu.Items.Add("Hide")
                                ElseIf wState = eWindowState.Hidden Then
                                    cMenu.Items.Add("Show")
                                End If
                                cMenu.Items.Add("Configure")
                                If Queue.WUs_Ready > 0 Then cMenu.Items.Add("Send all")
                                cMenu.Items.Add("-")
                                If MyClient.GuiController.StatsVisible Then
                                    cMenu.Items.Add("Close stats")
                                    cMenu.Items.Add("Popup stats")
                                Else
                                    cMenu.Items.Add("Show stats")
                                End If
                                cMenu.Items.Add("Show Queue")
                                cMenu.Items.Add("Show files")
                                _Nicon.ContextMenuStrip = cMenu
                                ' AddHandler _Nicon.MouseMove, AddressOf IconHover
                                _Nicon.Visible = True
                                _Nicon.BalloonTipTitle = ShortName
                                If Queue.ActiveSlot.Status = "1" Then
                                    _Nicon.BalloonTipText = "User: " & Queue.ActiveSlot.UserName & " (" & Queue.ActiveSlot.TeamNumber & ")" & vbNewLine
                                    _Nicon.BalloonTipText &= "Project: " & Queue.ActiveSlot.Project.Project & " (Run " & Queue.ActiveSlot.Project.Run & " Clone " & Queue.ActiveSlot.Project.Clone & " Gen " & Queue.ActiveSlot.Project.Gen & ")" & vbNewLine
                                    _Nicon.BalloonTipText &= "Issued: " & Queue.ActiveSlot.Issued.ToLongDateString & " " & Queue.ActiveSlot.Issued.ToLongTimeString & vbNewLine
                                    _Nicon.BalloonTipText &= "Expires: " & Queue.ActiveSlot.Expires.ToLongDateString & " " & Queue.ActiveSlot.Expires.ToLongTimeString & vbNewLine
                                    Dim eDate As New DateTime : eDate = Queue.Eta : Dim qPPD As Int16 = Queue.PPD_LastFrame
                                    If eDate <> #1/1/2000# Then _Nicon.BalloonTipText &= "Eta: " & eDate.ToShortDateString & " " & eDate.ToLongTimeString & vbTab
                                    If qPPD <> -1 And qPPD <> -2 Then _Nicon.BalloonTipText &= "Ppd: " & qPPD.ToString
                                Else
                                    _Nicon.BalloonTipText = "-No current info-"
                                End If
                            End If
                        Catch ex As Exception
                            'Log to window
                        End Try
                    End Sub

                    Private Sub UpdateIconInv(ByVal ics As iState)
                        Try
                            cMenu.Items.Clear()
                            Select Case ics
                                Case iState.Err
                                    _Nicon.Icon = My.Resources.fold_log_Warning
                                    'Add more code!                                       
                                Case iState.iStop
                                    cMenu.Items.Add("Start")
                                    _Nicon.Icon = My.Resources.Icon_stop
                                Case iState.iRun
                                    _Nicon.Icon = My.Resources.Icon_start
                                    cMenu.Items.Add("Stop")
                                Case iState.iPause
                                    _Nicon.Icon = My.Resources.Icon_stop 'No pause icon?
                                    cMenu.Items.Add("Continue")
                                    cMenu.Items.Add("Stop")
                                Case iState.iPause
                            End Select
                            If wState = eWindowState.Visible Then
                                cMenu.Items.Add("Hide")
                            ElseIf wState = eWindowState.Hidden Then
                                cMenu.Items.Add("Show")
                            End If
                            cMenu.Items.Add("Configure")
                            If Queue.WUs_Ready > 0 Then cMenu.Items.Add("Send all")
                            cMenu.Items.Add("-")
                            If MyClient.GuiController.StatsVisible Then
                                cMenu.Items.Add("Close stats")
                                cMenu.Items.Add("Popup stats")
                            Else
                                cMenu.Items.Add("Show stats")
                            End If
                            cMenu.Items.Add("Show Queue")
                            cMenu.Items.Add("Show files")
                            _Nicon.ContextMenuStrip = cMenu
                            ' AddHandler _Nicon.MouseMove, AddressOf IconHover
                            _Nicon.Visible = True
                            _Nicon.BalloonTipTitle = ShortName
                            If Queue.ActiveSlot.Status = "1" Then
                                _Nicon.BalloonTipText = "User: " & Queue.ActiveSlot.UserName & " (" & Queue.ActiveSlot.TeamNumber & ")" & vbNewLine
                                _Nicon.BalloonTipText &= "Project: " & Queue.ActiveSlot.Project.Project & " (Run " & Queue.ActiveSlot.Project.Run & " Clone " & Queue.ActiveSlot.Project.Clone & " Gen " & Queue.ActiveSlot.Project.Gen & ")" & vbNewLine
                                _Nicon.BalloonTipText &= "Issued: " & Queue.ActiveSlot.Issued.ToLongDateString & " " & Queue.ActiveSlot.Issued.ToLongTimeString & vbNewLine
                                _Nicon.BalloonTipText &= "Expires: " & Queue.ActiveSlot.Expires.ToLongDateString & " " & Queue.ActiveSlot.Expires.ToLongTimeString & vbNewLine
                                Dim eDate As New DateTime : eDate = Queue.Eta : Dim qPPD As Int16 = Queue.PPD_LastFrame
                                If eDate <> #1/1/2000# Then _Nicon.BalloonTipText &= "Eta: " & eDate.ToShortDateString & " " & eDate.ToLongTimeString & vbTab
                                If qPPD <> -1 And qPPD <> -2 Then _Nicon.BalloonTipText &= "Ppd: " & qPPD.ToString
                            Else
                                _Nicon.BalloonTipText = "-No current info-"
                            End If
                        Catch ex As Exception

                        End Try
                    End Sub

                    Public Sub HideIcon()
                        _Nicon.Visible = False
                    End Sub

                    Private Sub ShowConfig()
                        Cfg.CfgManager.ClientSettings.ShowConfig(MyClient)
                    End Sub

                    Private Sub ShowFiles()
                        Process.Start(ClientLocation & "\")
                    End Sub

                    Private Sub ShowQueue()
                        Dim fQueue As New frmQueue
                        If fTray.WindowState = FormWindowState.Normal Then
                            fQueue.ShowQueue(_MyClient, fTray)
                        Else
                            fQueue.ShowQueue(_MyClient)
                        End If
                    End Sub

                    Private Sub _Nicon_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles _Nicon.MouseClick
                        Select Case e.Button
                            Case MouseButtons.Left
                                'show/hide, exit now if service
                                If _Service Then Exit Sub
                                If wState = eWindowState.Visible Then
                                    HideConsole()
                                Else
                                    ShowConsole()
                                End If
                        End Select
                    End Sub

                    Private Sub cMenu_ItemClicked(ByVal sender As Object, ByVal e As System.Windows.Forms.ToolStripItemClickedEventArgs) Handles cMenu.ItemClicked
                        Select Case e.ClickedItem.Text
                            Case "Continue"
                                ContinueClient()
                            Case "Pause"
                                PauseClient()
                            Case "Start"
                                StartClient()
                            Case "Stop"
                                StopClient()
                            Case "Show"
                                ShowConsole()
                            Case "Hide"
                                HideConsole()
                            Case "Configure"
                                ShowConfig()
                            Case "Show files"
                                ShowFiles()
                            Case "Show Queue"
                                ShowQueue()
                            Case "Show stats"
                                Dim nStats As New frmEOC
                                If nStats.ShowSig(MyClient) Then
                                    fTray.Focus()
                                    MyClient.GuiController.StatsVisible = True
                                    MyClient.GuiController.StatsForm = nStats
                                End If
                            Case "Close stats"
                                MyClient.GuiController.StatsForm.Close()
                                MyClient.GuiController.StatsVisible = False
                            Case "Popup stats"
                                MyClient.GuiController.StatsForm.Visible = True
                            Case "Send all"
                                SendAll()
                        End Select
                    End Sub
#End Region

#Region "Send all"
                    Public bSendAllBussy As Boolean = False
                    Public Enum eSendAllResults
                        Err = -1
                        AllSend = 0
                        SomeSend = 1
                        NoneSend = 2
                    End Enum
                    Private _SendAllResults As eSendAllResults = eSendAllResults.Err
                    Private _iWuReady As Int16 = 0
                    Public Event SendAllDone(ByVal Client As clsClientConfigs.sClientSettings.sClient)
                    Private WithEvents _tSendTimer As New System.Timers.Timer, _tCloseIcon As New System.Timers.Timer
                    Private WithEvents _pSend As New Process, _nIconSend As New NotifyIcon
                    Public ReadOnly Property SendAllResults() As eSendAllResults
                        Get
                            Return _SendAllResults
                        End Get
                    End Property
                    Private Enum eSendIcon
                        Green
                        Yellow
                    End Enum
                    Private SendIcon As eSendIcon = eSendIcon.Green
                    Public Function SendAll() As Boolean
                        Try
                            If Queue.WUs_Ready = 0 Then
                                'Log to window
                                Return True
                            End If
                            If bSendAllBussy Then
                                'Log to window
                                Return True
                            End If
                            'Add an icon to indicate trying to send result
                            With _nIconSend
                                .Text = "Trying to send all results.."
                                .Icon = My.Resources.Green
                            End With
                            With _tSendTimer
                                .Interval = 500
                                .AutoReset = False
                            End With
                            bSendAllBussy = True
                            Try
                                'Make backup of ready units
                                _iWuReady = Queue.WUs_Ready
                                _pSend = New Process
                                With _pSend.StartInfo
                                    .FileName = ClientEXE
                                    .WorkingDirectory = Mid(ClientEXE, 1, ClientEXE.LastIndexOf("\"))
                                    .Arguments = "-send all"
                                    .WindowStyle = ProcessWindowStyle.Hidden
                                End With
                                _pSend.Start()
                                _pSend.EnableRaisingEvents = True
                                _nIconSend.Visible = True
                                _tSendTimer.Enabled = True
                            Catch ex As Exception
                                LogWindow.WriteError("clsGuiController, pSend.Start", Err)
                            End Try
                            Return True
                        Catch ex As Exception
                            LogWindow.WriteError("clsGuiController, SendAll()", Err)
                            Return False
                        End Try
                    End Function
                    Private Sub _tSendTimer_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs) Handles _tSendTimer.Elapsed
                        If _nIconSend.Visible Then
                            If SendIcon = eSendIcon.Green Then
                                _nIconSend.Icon = My.Resources.Yellow
                                SendIcon = eSendIcon.Yellow
                            Else
                                _nIconSend.Icon = My.Resources.Green
                                SendIcon = eSendIcon.Green
                            End If
                            _tSendTimer.Enabled = True
                        End If
                    End Sub
                    Private Sub tCloseIcon_Elapsed(ByVal Sender As Object, ByVal e As System.Timers.ElapsedEventArgs) Handles _tCloseIcon.Elapsed
                        If _nIconSend.Visible Then _nIconSend.Visible = False
                    End Sub
                    Private Sub _pSend_Exited(ByVal sender As Object, ByVal e As System.EventArgs) Handles _pSend.Exited
                        Try
                            _tSendTimer.Enabled = False
                            bSendAllBussy = False
                            Queue.ReadQueue()
                            If Queue.WUs_Ready = 0 Then
                                _SendAllResults = eSendAllResults.AllSend
                                _nIconSend.Icon = My.Resources.Green
                                _nIconSend.ShowBalloonTip(0, "Send all results", ShortName & vbNewLine & vbNewLine & "All finished work units have been send", ToolTipIcon.Info)
                            ElseIf Queue.WUs_Ready < _iWuReady Then
                                _SendAllResults = eSendAllResults.SomeSend
                                _nIconSend.Icon = My.Resources.Yellow
                                _nIconSend.ShowBalloonTip(0, "Send all results", ShortName & vbNewLine & vbNewLine & "Some finished work units have been send but not all", ToolTipIcon.Warning)
                            ElseIf Queue.WUs_Ready = _iWuReady Then
                                _SendAllResults = eSendAllResults.NoneSend
                                _nIconSend.ShowBalloonTip(0, "Send all results", ShortName & vbNewLine & vbNewLine & "No finished work units have been send", ToolTipIcon.Warning)
                            End If
                            With _tCloseIcon
                                .Interval = 15000
                                .AutoReset = False
                                .Enabled = True
                            End With
                        Catch ex As Exception
                            LogWindow.WriteError("clsGuiController, SendAllExit", Err)
                            bSendAllBussy = False
                            _SendAllResults = eSendAllResults.Err
                            _nIconSend.Icon = My.Resources.Warning
                            _nIconSend.ShowBalloonTip(0, "Send all results", ShortName & vbNewLine & vbNewLine & "Error while trying to send results, check the debug messages", ToolTipIcon.Error)
                        End Try
                    End Sub
                    Private Sub _nIconSend_BalloonTipClicked(ByVal sender As Object, ByVal e As System.EventArgs) Handles _nIconSend.BalloonTipClicked
                        _nIconSend.Visible = False
                        _tCloseIcon.Enabled = False
                    End Sub
                    Private Sub _nIconSend_BalloonTipClosed(ByVal sender As Object, ByVal e As System.EventArgs) Handles _nIconSend.BalloonTipClosed
                        _nIconSend.Visible = False
                        _tCloseIcon.Enabled = False
                    End Sub
                    Private Sub _nIconSend_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles _nIconSend.MouseClick
                        If Not bSendAllBussy Then
                            _nIconSend.Visible = False
                            _tCloseIcon.Enabled = False
                        End If
                    End Sub

#End Region

#Region "Custom tooltip window"

                    Private WithEvents tHover As New System.Timers.Timer
                    Private pMouse As New Point, rIcon As New Rectangle
                    Private bBalloon As Boolean = False
                    Private Sub IconHover(ByVal Sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles _Nicon.MouseMove
                        If _Nicon.Text = "" Then _Nicon.Text = ShortName & " - " & Queue.Progress & "%"
                        If Cfg.BalloonTipVisible Or Not mySettings.bShowBalloonTip Then Exit Sub
                        If tHover.Enabled Then
                            pMouse = e.Location
                            rIcon.Height = 2 : rIcon.Width = 2
                            rIcon.X = Cursor.Position.X - 1
                            rIcon.Y = Cursor.Position.Y - 1
                        Else
                            If bBalloon Then Exit Sub
                            tHover.Interval = 500
                            tHover.AutoReset = False
                            tHover.Enabled = True
                        End If
                    End Sub
                    Private Sub tHover_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs) Handles tHover.Elapsed
                        tHover.Enabled = False
                        If rIcon.Contains(Cursor.Position) Then
                            If Not Cfg.BalloonTipVisible Then
                                _Nicon.ShowBalloonTip(0)
                                Cfg.BalloonTipVisible = True
                            End If
                        End If
                    End Sub
                    Private Sub BalloonClosed(ByVal Sender As Object, ByVal e As System.EventArgs) Handles _Nicon.BalloonTipClicked
                        Cfg.BalloonTipVisible = False
                    End Sub
                    Private Sub BalloonClicked() Handles _Nicon.BalloonTipClosed
                        Cfg.BalloonTipVisible = False
                    End Sub

#End Region

#Region "Filesystem watchers"
                    Private WithEvents tServiceCheck As New System.Timers.Timer
                    Private _scState As New ServiceControllerStatus
                    Public Function StartWatching()
                        'Testing queue class updates
                        Try
                            InitEOC()
                            _Stats = New clsStats(MyClient)
                            If AttachToSC() Then
                                _scState = _sCont.Status
                                tServiceCheck.Interval = mySettings.iServiceCheckInterval
                                tServiceCheck.AutoReset = False
                                tServiceCheck.Enabled = True
                            End If
                            Return Queue.StartWatching()
                        Catch ex As Exception
                            Return False
                        End Try
                    End Function
                    Public Sub StopWatching()
                        Try
                            tServiceCheck.Enabled = False
                            Queue.StopWatching()
                        Catch ex As Exception
                            'Log to window
                        End Try
                    End Sub
                    Private Sub tServiceCheck_Tick(ByVal Sender As Object, ByVal e As System.Timers.ElapsedEventArgs) Handles tServiceCheck.Elapsed
                        If AttachToSC() Then
                            If _scState <> _sCont.Status Then
                                _scState = _sCont.Status
                                StartUpdate(True)
                            End If
                            tServiceCheck.Enabled = True
                        Else
                            'ídk 
                            tServiceCheck.Enabled = False
                            StartUpdate(True)
                        End If
                    End Sub
                    Public Sub ExitHandler()
                        StartUpdate(True)
                    End Sub
                    Private Sub _cProc_Exited(ByVal sender As Object, ByVal e As System.EventArgs) Handles _cProc.Exited
                        StartUpdate(True)
                    End Sub



#End Region

#Region "Client project information"

                    Private _lQueue As clsQueue 'Double declared
                    Private WithEvents _Queue As clsQueue
                    Private _CurProject As String = vbNullString

                    Public ReadOnly Property QueueIndex() As Int16
                        Get
                            Try
                                Return _Queue.Current
                            Catch ex As Exception
                                Return -1
                            End Try
                        End Get
                    End Property

                    Public Function ReadQueue(Optional ByVal FirstRun As Boolean = False) As Boolean
                        Try
                            _Queue.ReadQueue()
                            If FirstRun Then _Queue.InitQueue()
                            Return Not (_Queue.HasError)
                        Catch ex As Exception
                            Return False
                        End Try
                    End Function

                    Public ReadOnly Property QueueError() As clsQueue.s_Err
                        Get
                            Try
                                Return _Queue.LastError
                            Catch ex As Exception
                                Dim rVal As New clsQueue.s_Err
                                rVal.Description = "Queue not initialised"
                                Return rVal
                            End Try
                        End Get
                    End Property

                    Public ReadOnly Property CurrentProject() As clsQueue.Entry
                        Get
                            Try
                                Return _Queue.ActiveSlot
                            Catch ex As Exception
                                Dim sVal As New clsQueue.Entry
                                Return sVal
                            End Try
                        End Get
                    End Property

                    Public Sub ClearQueue()
                        _Queue = New clsQueue(MyClient.GuiController.ClientLocation)
                        If mySettings.bAutoReload Then _Queue.StartWatching()
                    End Sub

                    Public ReadOnly Property Queue() As clsQueue
                        Get
                            Try
                                Return _Queue
                            Catch ex As Exception
                                _Queue = New clsQueue(ClientLocation)
                                If mySettings.bAutoReload Then _Queue.StartWatching()
                                Return _Queue
                            End Try
                        End Get
                    End Property

#End Region

#Region "Update from Queue class?"

                    Private Sub _Queue_ProjectEnd(ByVal Slot As clsQueue.Entry, ByVal tsFrame As TimeSpan, ByVal dtFrameStart As DateTime, ByVal Percentage As Short) Handles _Queue.ProjectEnd
                        _Stats.ActivePRGC.QueuSlot = Slot
                        If _Stats.ActivePRGC.AddFrame(tsFrame, dtFrameStart, Percentage) Then _Stats.Update()
                    End Sub

                    Private Sub _Queue_SuccesfullUpload(ByVal Slot As clsQueue.Entry) Handles _Queue.SuccesfullUpload
                        '
                    End Sub

                    Private Sub _Queue_EUE(ByVal CoreStatus As clsQueue.clsCoreStatus) Handles _Queue.EUE
                        'Show eue window
                        NotifyEUE(CoreStatus)
                    End Sub
                    Private Sub _Queue_NewFrame(ByVal CurrentProgress As Int16, ByVal FrameTime As TimeSpan, ByVal dtFrameEnd As DateTime) Handles _Queue.NewFrame
                        If _Stats.ActivePRGC.AddFrame(FrameTime, dtFrameEnd, CurrentProgress) Then _Stats.Update()
                        If _bWaitUnit And _bWaitFrame Then
                            _bWaitFrame = False
                            _bWaitUnit = False
                            StopClient()
                            StartClient("-oneunit", True)
                        ElseIf _bWaitFrame And Not _bWaitUnit Then
                            _bWaitFrame = False
                            StopClient()
                        End If
                        StartUpdate(True)
                    End Sub

                    Private Sub _Queue_ProjectStart(ByVal Slot As clsQueue.Entry) Handles _Queue.ProjectStart
                        _Stats = New clsStats(MyClient)
                    End Sub

                    Public Function NotifyEUE(ByVal CoreStatus As clsQueue.clsCoreStatus) As Boolean
                        Dim nEue As New frmEUE
                        nEue.nIcon.Icon = My.Resources.fold_log_Warning
                        nEue.NotifyEUE(CoreStatus)
                    End Function

                    Public Function StartUpdate(Optional ByVal Overide As Boolean = False) As Boolean
                        Try
                            Try
                                EOCStats.RefreshEOC()
                                ' update icon 
                                If mySettings.bClientIcons Then
                                    If MyClient.PandeGroup.ServiceMode Then
                                        If Not AttachToSC() Then
                                            'Log to window
                                            Return False
                                        End If
                                        If ServiceState = eServiceState.Err Then
                                            ShowIcon(iState.Err)
                                        ElseIf ServiceState = eServiceState.Paused Then
                                            ShowIcon(iState.iPause)
                                        ElseIf ServiceState = eServiceState.Running Then
                                            ShowIcon(iState.iRun)
                                        ElseIf ServiceState = eServiceState.Stopped Then
                                            ShowIcon(iState.iStop)
                                        End If
                                    Else
                                        If Running(True) Then
                                            ShowIcon(clsClientConfiguration.clsClientConfigs.sClientSettings.sClient.clsGUIController.iState.iRun)
                                        Else
                                            ShowIcon(clsClientConfiguration.clsClientConfigs.sClientSettings.sClient.clsGUIController.iState.iStop)
                                        End If
                                    End If
                                End If
                            Catch ex As Exception
                                LogWindow.WriteError("clsClientControl, sClient, GuiController, StartUpdate(" & Overide.ToString & ")", Err, ex.Message)
                            End Try
                            fTray.UpdateClientInvoked(MyClient)
                            Return True
                        Catch ex As Exception
                            LogWindow.WriteError("clsClientControl, sClient, GuiController, StartUpdate(" & Overide.ToString & ")", Err, ex.Message)
                            Return False
                        End Try
                    End Function

#End Region

#Region "Stats"
#Region "EOC"
                    'EOC class
                    Private WithEvents _EOCSTATS As clsEOC
                    Private _bEOCInit As Boolean = False
                    Public ReadOnly Property EOCStats() As clsEOC
                        Get
                            If Not _bEOCInit Then
                                _EOCSTATS = New clsEOC(MyClient.PandeGroup.UserName, MyClient.PandeGroup.TeamNumber)
                                _bEOCInit = True
                            End If
                            Return _EOCSTATS
                        End Get
                    End Property
                    Public Function InitEOC() As Boolean
                        Try
                            If _bEOCInit Then Return True
                            _EOCSTATS = New clsEOC(MyClient.PandeGroup.UserName, MyClient.PandeGroup.TeamNumber)
                            Return _EOCSTATS.Filled
                        Catch ex As Exception
                            LogWindow.WriteError("Guicontroller, InitEOC", Err, ex.Message)
                            Return False
                        End Try
                    End Function
                    'Eoc trayform
                    Private _StatsVisible As Boolean = False
                    Private _StatsForm As New Form
                    Public Property StatsVisible() As Boolean
                        Get
                            Return _StatsVisible
                        End Get
                        Set(ByVal value As Boolean)
                            _StatsVisible = value
                            If value = False Then _StatsForm = New Form
                        End Set
                    End Property
                    Public Property StatsForm() As Form
                        Get
                            Return _StatsForm
                        End Get
                        Set(ByVal value As Form)
                            _StatsForm = value
                        End Set
                    End Property
#End Region
#Region "Local"
                    Private _Stats As clsStats
                    Public ReadOnly Property Statistics() As clsStats
                        Get
                            Try
                                If _Stats.ActivePRGC.KnownFrames = 0 Then
                                    _Stats = New clsStats(MyClient)
                                End If
                                Return _Stats
                            Catch ex As Exception
                                _Stats = New clsStats(MyClient)
                                Return _Stats
                            End Try
                        End Get
                    End Property
#End Region
#End Region

                    
                End Class

                Public PandeGroup As New clsPandeGroup

                Public WithEvents GuiController As New clsGUIController

            End Class

            Public WithEvents Client As New sClient
            Public Shared fConfig As frmConfig

            Public Function AddClient(ByVal aClient As sClient) As Boolean
                Try
                    If colClients.Contains(aClient.GuiController.ClientLocation) Then Return False
                    colClients.Add(aClient)
                    'Add prefered settings
                    Dim pSettings As clsClientConfiguration.clsClientConfigs.sPerferdConfig.sSingleClient = Cfg.CfgManager.PrefferedSettings.GetPreffered(aClient.GuiController.TypeOfClient)
                    With aClient.PandeGroup
                        .AcceptedWUSize = pSettings.WuSize
                        .AdditionalParameters = pSettings.AdditionalParameter
                        .AddRemoveService = pSettings.LaunchService
                        .AskNetwork = pSettings.AskNetwork
                        .CheckpointInterval = pSettings.CPInterval
                        .CorePriority = pSettings.CorePriority
                        .CpuUsage = pSettings.CpuUsage
                        .DisableAffinitylock = pSettings.DisableAffinityLock
                        .DisableAssembly = pSettings.DisableAssembly
                        .ForceAdvMethods = pSettings.AdvancedMethods
                        .IgnoreDeadline = pSettings.IgnoreLocalDeadlines
                        .PauseBattery = pSettings.PauseBattery
                        .UserName = ""
                        .TeamNumber = ""
                        .PassKey = ""
                        'Edit here!
                        .MachineID = colClients.Count.ToString
                        .ClientType = aClient.GuiController.TypeOfClient
                        If aClient.GuiController.TypeOfClient > 5 And aClient.GuiController.TypeOfClient <> sClient.clsGUIController.eClient.CPU Then
                            'gpu
                            If .AdditionalParameters.Length > 0 Then
                                .AdditionalParameters = .AdditionalParameters & " -gpu " & intGpu
                            Else
                                .AdditionalParameters = .AdditionalParameters & "-gpu " & intGpu
                            End If
                            intGpu += 1
                        End If
                    End With
                    'Do first config 
                    Dim fConfig As New frmConfig()
                    fConfig.StartConfig(aClient, True, True, True)
                    While Not fConfig.Done And Not _ExitAPP
                        Application.DoEvents()
                    End While
                    If _ExitAPP Then End
                    aClient = fConfig.Client
                    fConfig.Close()
                    Return SaveConfig(aClient)
                Catch ex As Exception
                    Return False
                End Try
            End Function
            Private _cfgClient As New sClient
            Public Function ShowConfig(ByVal Client As clsClientConfigs.sClientSettings.sClient, Optional ByVal FirstTime As Boolean = False) As Boolean
                Try
                    If fTray.WindowState = FormWindowState.Normal Then
                        fConfig = New frmConfig()
                        fConfig.bDialog = True
                        fConfig.aClient = Client
                        fConfig.NoCancel = False
                        If Not FirstTime Then
                            _cfgClient = Client
                            AddHandler fConfig.FormClosed, AddressOf RefreshAfterConfig
                        End If
                        fConfig.ShowDialog(fTray)
                    Else
                        Dim tShow As New Threading.Thread(AddressOf tShowConfig)
                        tShow.Priority = Threading.ThreadPriority.BelowNormal
                        tShow.Start(Client)
                    End If
                Catch ex As Exception
                    'Log to window 
                    Return False
                End Try
            End Function

            Private Sub tShowConfig(ByVal Client As clsClientConfiguration.clsClientConfigs.sClientSettings.sClient)
                Try
                    fConfig = New frmConfig
                    fConfig.bDialog = True
                    fConfig.NoCancel = False
                    fConfig.aClient = Client
                    _cfgClient = Client
                    AddHandler fConfig.FormClosed, AddressOf RefreshAfterConfig
                    Application.Run(fConfig)
                Catch ex As Exception
                    'Log to window
                End Try
            End Sub

            Private Sub RefreshAfterConfig()
                Try
                    _cfgClient.GuiController.StartUpdate(True)
                Catch ex As Exception
                    'Log to window

                End Try
            End Sub

            Public Function LoadConfig(ByVal Client As sClient) As sClient
                Try
                    Dim xFile As String = Client.GuiController.ClientLocation & "\maxFAH-GUI.xml"
                    Dim xReader As XmlReader = XmlReader.Create(xFile)
                    With xReader
                        .ReadStartElement() 'maxfahgui
                        .ReadStartElement() 'guicontroller
                        Client.GuiController.ClientVersion = .ReadElementString
                        Client.GuiController.ClientLocation = .ReadElementString
                        Client.GuiController.ClientEXE = .ReadElementString
                        Dim tStr As String = .ReadElementString
                        Select Case tStr
                            Case Is = "CPU"
                                Client.GuiController.TypeOfClient = sClient.clsGUIController.eClient.CPU
                            Case Is = "SXD"
                                Client.GuiController.TypeOfClient = 1
                            Case Is = "SXM"
                                Client.GuiController.TypeOfClient = 2
                            Case Is = "SVD"
                                Client.GuiController.TypeOfClient = 3
                            Case Is = "SVM"
                                Client.GuiController.TypeOfClient = 4
                            Case Is = "GXA"
                                Client.GuiController.TypeOfClient = 5
                            Case Is = "GXN"
                                Client.GuiController.TypeOfClient = 6
                            Case Is = "GVA"
                                Client.GuiController.TypeOfClient = 7
                            Case Is = "GVN"
                                Client.GuiController.TypeOfClient = 8
                        End Select
                        Client.GuiController.Ordinal = .ReadElementString("Ordinal")
                        Dim xInt As Int16 = CInt(.ReadElementString("APcount"))
                        If xInt >= 1 Then
                            For yInt As Int16 = 1 To xInt
                                Client.GuiController.PrioritySettings(yInt) = .ReadElementString("Priority")
                                Client.GuiController.AffintySettings(yInt) = .ReadElementString("Affinity")
                            Next
                        End If
                        .ReadEndElement() 'guicontroller
                        .ReadStartElement() 'Pandegroup
                        Client.PandeGroup.UserName = .ReadElementString
                        Client.PandeGroup.TeamNumber = .ReadElementString
                        Client.PandeGroup.PassKey = .ReadElementString
                        Client.PandeGroup.AskNetwork = .ReadElementString
                        Client.PandeGroup.UseProxy = .ReadElementString
                        Client.PandeGroup.UseProxyPassword = .ReadElementString
                        Client.PandeGroup.ProxyHost = .ReadElementString
                        Client.PandeGroup.ProxyPort = .ReadElementString
                        Client.PandeGroup.ProxyUserName = .ReadElementString
                        Client.PandeGroup.ProxyPassword = .ReadElementString
                        Client.PandeGroup.IsService = .ReadElementString
                        Client.PandeGroup.AcceptedWUSize = .ReadElementString
                        Client.PandeGroup.CorePriority = .ReadElementString
                        Client.PandeGroup.CpuUsage = .ReadElementString
                        Client.PandeGroup.DisableAssembly = .ReadElementString
                        Client.PandeGroup.PauseBattery = .ReadElementString
                        Client.PandeGroup.CheckpointInterval = .ReadElementString
                        Client.PandeGroup.MemoryUsage = .ReadElementString
                        Client.PandeGroup.ForceAdvMethods = .ReadElementString
                        Client.PandeGroup.IgnoreDeadline = .ReadElementString
                        Client.PandeGroup.MachineID = .ReadElementString
                        Client.PandeGroup.DisableAffinitylock = .ReadElementString
                        Client.PandeGroup.AdditionalParameters = .ReadElementString
                        Client.PandeGroup.IPAdress = .ReadElementString
                        .Close()
                    End With
                    Return Client
                Catch ex As Exception
                    Debug.Print(ex.Message)
                    Return Nothing
                End Try
            End Function

            Public Function SaveConfig(ByVal Client As sClient) As Boolean
                Try
                    'One xml file per client, located in the client folder, maxFAH-GUI.xml
                    Dim xFile As String = Client.GuiController.ClientLocation & "\maxFAH-GUI.xml"
                    Dim xWriter As XmlWriter = XmlWriter.Create(xFile)
                    With xWriter
                        .WriteStartDocument()
                        .WriteStartElement("maxFAH-GUI")
                        .WriteStartElement("GUI-controller")
                        .WriteElementString("Version", Client.GuiController.ClientVersion)
                        .WriteElementString("Location", Client.GuiController.ClientLocation)
                        .WriteElementString("Executable", Client.GuiController.ClientEXE)
                        .WriteElementString("ClientType", Client.GuiController.TypeOfClient.ToString)
                        .WriteElementString("Ordinal", Client.GuiController.Ordinal.ToString)
                        .WriteElementString("APcount", Client.GuiController.APcount.ToString)
                        If Client.GuiController.APcount >= 1 Then
                            For xInt As Int16 = 1 To Client.GuiController.APcount
                                .WriteElementString("Priority", Client.GuiController.PrioritySettings(xInt).ToString)
                                .WriteElementString("Affinity", Client.GuiController.AffintySettings(xInt).ToString)
                            Next
                        End If
                        .WriteEndElement()
                        .WriteStartElement("PandeGroup")
                        .WriteElementString("UserName", Client.PandeGroup.UserName)
                        .WriteElementString("TeamNumber", Client.PandeGroup.TeamNumber)
                        .WriteElementString("PassKey", Client.PandeGroup.PassKey)
                        .WriteElementString("AskNetwork", Client.PandeGroup.AskNetwork)
                        .WriteElementString("UseProxy", Client.PandeGroup.UseProxy)
                        .WriteElementString("UseProxyPassword", Client.PandeGroup.UseProxyPassword)
                        .WriteElementString("ProxyName", Client.PandeGroup.ProxyHost)
                        .WriteElementString("ProxyPort", Client.PandeGroup.ProxyPort)
                        .WriteElementString("ProxyUserName", Client.PandeGroup.ProxyUserName)
                        .WriteElementString("ProxyPassword", Client.PandeGroup.ProxyPassword)
                        .WriteElementString("ServiceMode", Client.PandeGroup.IsService.ToString)
                        .WriteElementString("WuSize", Client.PandeGroup.AcceptedWUSize)
                        .WriteElementString("CorePriority", Client.PandeGroup.CorePriority)
                        .WriteElementString("CpuUsage", Client.PandeGroup.CpuUsage)
                        .WriteElementString("DisableAssembly", Client.PandeGroup.DisableAssembly)
                        .WriteElementString("PauseBattery", Client.PandeGroup.PauseBattery)
                        .WriteElementString("CheckPoint", Client.PandeGroup.CheckpointInterval)
                        .WriteElementString("Memory", Client.PandeGroup.MemoryUsage)
                        .WriteElementString("AdvancedMethods", Client.PandeGroup.ForceAdvMethods)
                        .WriteElementString("IgnoreDeadlines", Client.PandeGroup.IgnoreDeadline)
                        .WriteElementString("MachineID", Client.PandeGroup.MachineID)
                        .WriteElementString("DisableAffinityLock", Client.PandeGroup.DisableAffinitylock)
                        .WriteElementString("Parameters", Client.PandeGroup.AdditionalParameters)
                        .WriteElementString("IPadress", Client.PandeGroup.IPAdress)
                        .WriteEndElement()
                        .WriteEndDocument()
                        .Flush()
                        .Close()
                    End With
                    Return True
                Catch ex As Exception
                    Return False
                End Try
            End Function
        End Class

        Public Function GetClient(ByVal strClientID As String) As sClientSettings  'clientID is servicename
            Try
                If colClients.Contains(strClientID) Then
                    Return colClients(strClientID)
                Else
                    Return Nothing
                End If
            Catch ex As Exception
                Return Nothing
            End Try
        End Function

#Region "Prefered confgig and setup manager"
        Public Structure sPerferdConfig
            Public Enum eClient
                Empty = 0
                SXD = 1
                SXM = 2
                SVD = 3
                SVM = 4
                GXA = 5
                GXN = 6
                GVA = 7
                GVN = 8
                CPU = 9
            End Enum
            Public Structure sSingleClient
                Public Enum eClient
                    Empty = 0
                    SXD = 1
                    SXM = 2
                    SVD = 3
                    SVM = 4
                    GXA = 5
                    GXN = 6
                    GVA = 7
                    GVN = 8
                    CPU = 9
                End Enum
                Public Function ParseType(ByVal Text As String)
                    Select Case Text.ToUpper
                        Case Is = "CPU"
                            TypeOfClient = eClient.CPU
                        Case Is = "SXD"
                            TypeOfClient = eClient.SXD
                        Case Is = "SXM"
                            TypeOfClient = eClient.SXM
                        Case Is = "SVD"
                            TypeOfClient = eClient.SVD
                        Case Is = "SVM"
                            TypeOfClient = eClient.SVM
                        Case Is = "GXA"
                            TypeOfClient = eClient.GXA
                        Case Is = "GXN"
                            TypeOfClient = eClient.GXN
                        Case Is = "GVA"
                            TypeOfClient = eClient.GVA
                        Case Is = "GVN"
                            TypeOfClient = eClient.GVN
                    End Select
                    Return True
                End Function
                Public TypeOfClient As eClient
                Public CPInterval As String, LockCPInterval As Boolean
                Public AskNetwork As String, LockAskNetwork As Boolean
                Public LaunchService As String, LockLaunchService As Boolean, WuSize As String, LockWuSize As Boolean
                Public CorePriority As String, LockCorePriority As Boolean, CpuUsage As String, LockCpuUsage As Boolean
                Public DisableAssembly As String, LockDisableAssembly As Boolean, LockDisableAffinityLock As Boolean
                Public PauseBattery As String, LockPauseBattery As Boolean, AdvancedMethods As String, LockAdvancedMethods As Boolean
                Public IgnoreLocalDeadlines As String, LockIgnoreLocalDeadlines As Boolean, DisableAffinityLock As String
                Public AdditionalParameter As String, LockAdditionalParameters As Boolean, UserName As String, TeamNumber As String, PassKey As String
            End Structure
            Private psClient As sSingleClient
            Private colClients As Collection
            Public ReadOnly Property IsEmpty() As Boolean
                Get
                    Try
                        If colClients.Count = 0 Then
                            Return True
                        Else
                            Return False
                        End If
                    Catch ex As Exception
                        Return True
                    End Try
                End Get
            End Property
            Public ReadOnly Property GetPreffered(ByVal ClientType As eClient) As sSingleClient
                Get
                    Try
                        Return colClients(ClientType.ToString)
                    Catch ex As Exception
                        Return Nothing
                    End Try
                End Get
            End Property
            Public Function AddToPreferred(ByVal ClientType As eClient, ByVal Settings As sSingleClient) As Boolean
                Try
                    If colClients.Contains(ClientType.ToString) Then colClients.Remove(ClientType.ToString)
                    colClients.Add(Settings, ClientType.ToString)
                    Return True
                Catch ex As Exception
                    Return False
                End Try
            End Function
            Public Function WriteToXML(ByVal xWriter As XmlWriter, ByVal frmX As frmXmlCreator) As Boolean
                Try
                    If IsEmpty Then Return True
                    With xWriter
                        .WriteStartElement("PreferredSettings")
                        For Each Client As sSingleClient In colClients
                            .WriteStartElement("Client")
                            .WriteElementString("ClientType", Client.TypeOfClient.ToString)
                            .WriteElementString("AskNetwork", Client.AskNetwork)
                            .WriteElementString("LockAskNetwork", Client.LockAskNetwork.ToString)
                            .WriteElementString("LaunchService", Client.LaunchService)
                            .WriteElementString("LockLaunchService", Client.LockLaunchService.ToString)
                            .WriteElementString("WuSize", Client.WuSize)
                            .WriteElementString("LockWuSize", Client.LockWuSize.ToString)
                            .WriteElementString("CorePriority", Client.CorePriority)
                            .WriteElementString("LockCorePriority", Client.LockCorePriority.ToString)
                            .WriteElementString("CpuUsage", Client.CpuUsage)
                            .WriteElementString("LockCpuUsage", Client.LockCpuUsage.ToString)
                            .WriteElementString("DisableAssembly", Client.DisableAssembly)
                            .WriteElementString("LockDisableAssembly", Client.LockDisableAssembly.ToString)
                            .WriteElementString("PauseBattery", Client.PauseBattery)
                            .WriteElementString("LockPauseBattery", Client.LockPauseBattery.ToString)
                            .WriteElementString("CPInterval", Client.CPInterval)
                            .WriteElementString("LockCPInterval", Client.LockCPInterval.ToString)
                            .WriteElementString("AdvancedMethods", Client.AdvancedMethods)
                            .WriteElementString("LockAdvancedMethods", Client.LockAdvancedMethods.ToString)
                            .WriteElementString("IgnoreLocalDeadlines", Client.IgnoreLocalDeadlines)
                            .WriteElementString("LockIgnoreLocalDeadlines", Client.LockIgnoreLocalDeadlines.ToString)
                            .WriteElementString("DisableAffinityLock", Client.DisableAffinityLock)
                            .WriteElementString("LockDisableAffinityLock", Client.LockDisableAffinityLock.ToString)
                            .WriteElementString("AdditionalParameters", Client.AdditionalParameter)
                            .WriteElementString("LockAdditionalParameters", Client.LockAdditionalParameters.ToString)
                            'Add clients priority and affinity settings here!


                            .WriteEndElement()
                        Next
                        .WriteEndElement()
                        .WriteEndDocument()
                        .Flush()
                        .Close()
                    End With
                    Return True
                Catch ex As Exception
                    Return False
                End Try
            End Function
            Public Function ReadFromXML(ByVal xReader As XmlReader) As Boolean
                Try
                    xReader.ReadStartElement("PreferredSettings")
                    Dim nPsettings As New sPerferdConfig.sSingleClient
                    'On Error Resume Next
                    If colClients.Count = 0 Then colClients = New Collection
                    Do While xReader.EOF = False
                        With xReader
                            .ReadStartElement() 'Tag
                            nPsettings.ParseType(.ReadElementString("ClientType"))
                            nPsettings.AskNetwork = .ReadElementString("AskNetwork")
                            nPsettings.LockAskNetwork = CBool(.ReadElementString("LockAskNetwork"))
                            nPsettings.LaunchService = .ReadElementString("LaunchService")
                            nPsettings.LockLaunchService = CBool(.ReadElementString("LockLaunchService"))
                            nPsettings.WuSize = .ReadElementString("WuSize")
                            nPsettings.LockWuSize = CBool(.ReadElementString("LockWuSize"))
                            nPsettings.CorePriority = .ReadElementString("CorePriority")
                            nPsettings.LockCorePriority = CBool(.ReadElementString("LockCorePriority"))
                            nPsettings.CpuUsage = .ReadElementString("CpuUsage")
                            nPsettings.LockCpuUsage = CBool(.ReadElementString("LockCpuUsage"))
                            nPsettings.DisableAssembly = .ReadElementString("DisableAssembly")
                            nPsettings.LockDisableAssembly = CBool(.ReadElementString("LockDisableAssembly"))
                            nPsettings.PauseBattery = .ReadElementString("PauseBattery")
                            nPsettings.LockPauseBattery = CBool(.ReadElementString("LockPauseBattery"))
                            nPsettings.CPInterval = .ReadElementString("CPInterval")
                            nPsettings.LockCPInterval = CBool(.ReadElementString("LockCPInterval"))
                            nPsettings.AdvancedMethods = .ReadElementString("AdvancedMethods")
                            nPsettings.LockAdvancedMethods = CBool(.ReadElementString("LockAdvancedMethods"))
                            nPsettings.IgnoreLocalDeadlines = .ReadElementString("IgnoreLocalDeadlines")
                            nPsettings.LockIgnoreLocalDeadlines = CBool(.ReadElementString("LockIgnoreLocalDeadlines"))
                            nPsettings.DisableAffinityLock = .ReadElementString("DisableAffinityLock")
                            nPsettings.LockDisableAffinityLock = CBool(.ReadElementString("LockDisableAffinityLock"))
                            nPsettings.AdditionalParameter = .ReadElementString("AdditionalParameters")
                            nPsettings.LockAdditionalParameters = CBool(.ReadElementString("LockAdditionalParameters"))
                            'Read clients priority and affinity settings here!
                            .ReadEndElement() 'tag
                            If Not colClients.Contains(nPsettings.TypeOfClient.ToString) Then colClients.Add(nPsettings, nPsettings.TypeOfClient.ToString)
                        End With
                    Loop
                    xReader.Close()
                    xReader = Nothing
                    Return True
                Catch ex As Exception
                    xReader.Close()
                    xReader = Nothing
                    Return (colClients.Count > 0)
                End Try

            End Function
            Public Sub Init()
                colClients = New Collection
            End Sub
        End Structure
        Public Structure sSetupManager
            Private _RootFolder As String
            Private _ClientFolder As String
            Public ReadOnly Property RootFolder() As String
                Get
                    Return _RootFolder
                End Get
            End Property
            Public Enum eClient
                Empty = 0
                SXD = 1
                SXM = 2
                SVD = 3
                SVM = 4
                GXA = 5
                GXN = 6
                GVA = 7
                GVN = 8
                CPU = 9
            End Enum
            Public ReadOnly Property ClientFolder() As String
                Get
                    Return _ClientFolder
                End Get
            End Property
            Private _NotEmpty As Boolean
            Public ReadOnly Property NotEmpty() As Boolean
                Get
                    Return _NotEmpty
                End Get
            End Property
            Public Function DownloadClient(ByVal ClientType As eClient) As Boolean
                Try
                    'Here we are!
                    Dim fName As String
                    Select Case ClientType
                        Case eClient.CPU
                            GoTo DoCPU
                        Case eClient.GVA
                            GoTo DoGpuVista
                        Case eClient.GVN
                            GoTo DoGpuVista
                        Case eClient.GXA
                            GoTo DoGpuXP
                        Case eClient.GXN
                            GoTo DoGpuXP
                        Case eClient.SVD
                            GoTo DoDeino
                        Case eClient.SVM
                            GoTo DoMpich
                        Case eClient.SXD
                            GoTo DoDeino
                        Case eClient.SXM
                            GoTo DoMpich
                    End Select
DoCPU:
                    'Download cpu client
                    fName = ClientFolder & "\" & Mid(formXML.txtCpuURL.Text, formXML.txtCpuURL.Text.LastIndexOf("/") + 2)
                    If My.Computer.FileSystem.FileExists(fName) Then Return Uniprocessor()
                    formDownload.Show()
                    formDownload.download(formXML.txtCpuURL.Text, formDownload.PbarDownload, fName)
                    formDownload.Hide()
                    Return Uniprocessor()
DoMpich:
                    'Download mpich
                    fName = ClientFolder & "\" & Mid(MpichUrl, MpichUrl.LastIndexOf("/") + 2)
                    If My.Computer.FileSystem.FileExists(fName) Then Return InitialMPICH()
                    formDownload.Show()
                    formDownload.download(MpichUrl, frmDownloadClients.PbarDownload, fName)
                    formDownload.Hide()
                    Return InitialMPICH()
DoDeino:
                    fName = ClientFolder & "\" & Mid(DeinoUrl, DeinoUrl.LastIndexOf("/") + 2)
                    If My.Computer.FileSystem.FileExists(fName) Then Return initialDEINO()
                    formDownload.Show()
                    formDownload.download(DeinoUrl, frmDownloadClients.PbarDownload, fName)
                    formDownload.Hide()
                    Return initialDEINO()
DoGpuVista:
                    'remove later
                    fName = ClientFolder & "\" & Mid(ClientInfo(eClient.GVA).Url, ClientInfo(eClient.GVA).Url.LastIndexOf("/") + 2)
                    If My.Computer.FileSystem.FileExists(fName) Then Return GpuVista()
                    formDownload.Show()
                    formDownload.download(ClientInfo(eClient.GVA).Url, frmDownloadClients.PbarDownload, fName)
                    formDownload.Hide()
                    Return GpuVista()
DoGpuXP:
                    fName = ClientFolder & "\" & Mid(ClientInfo(eClient.GXA).Url, ClientInfo(eClient.GXA).Url.LastIndexOf("/") + 2)
                    If My.Computer.FileSystem.FileExists(fName) Then Return GpuXP()
                    formDownload.Show()
                    formDownload.download(ClientInfo(eClient.GXA).Url, frmDownloadClients.PbarDownload, fName)
                    formDownload.Hide()
                    Return GpuXP()
                Catch ex As Exception
                    Return False
                End Try
            End Function
            Private Function InitialMPICH() As Boolean
                Try
                    'Check for already installed
                    Dim scServices() As ServiceController, _boolIsInstalled As Boolean = False
                    scServices = ServiceController.GetServices()
                    For Each sService In scServices
                        If sService.ServiceName.ToUpper.Contains("MPICH2 PROCESS MANAGER") Or sService.DisplayName.ToUpper.Contains("MPICH2 PROCESS MANAGER") Then
                            If sService.Status = ServiceControllerStatus.Running Then
                                Return True 'Edit back
                            End If
                        End If
                    Next
Check:
                    Dim hUn2 As IntPtr
                    Dim hUninstall As IntPtr
                    Dim hWelcome As IntPtr
                    Dim hReadme As IntPtr
                    Dim hDprofile As IntPtr
                    Dim hDestination As IntPtr
                    Dim hStartCopy As IntPtr
                    Dim hComplete As IntPtr
                    'look for other windows!
                    hWelcome = FindWindow("#32770", "Welcome")
                    hUninstall = FindWindow("#32770", "Setup V2.31")
                    hUn2 = FindWindow("#32770", "Uninstall")
                    hReadme = FindWindow("#32770", "Readme Information")
                    hDprofile = FindWindow("#32770", "Destination Profile Selection")
                    hDestination = FindWindow("#32770", "Choose Destination Directory")
                    hStartCopy = FindWindow("#32770", "Start Copying Files")
                    hComplete = FindWindow("#32770", "Setup Complete")
                    Dim lbcloseFirst As New ListBox
                    lbcloseFirst.Items.Clear()
                    If hWelcome <> 0 Then lbcloseFirst.Items.Add("Welcome")
                    If hUninstall <> 0 Then lbcloseFirst.Items.Add("Setup V2.31")
                    If hUn2 <> 0 Then lbcloseFirst.Items.Add("Uninstall")
                    If hReadme <> 0 Then lbcloseFirst.Items.Add("Readme information")
                    If hDprofile <> 0 Then lbcloseFirst.Items.Add("Destination Profile Selection")
                    If hDestination <> 0 Then lbcloseFirst.Items.Add("Choose Destination Directory")
                    If hStartCopy <> 0 Then lbcloseFirst.Items.Add("Start Copying Files")
                    If hComplete <> 0 Then lbcloseFirst.Items.Add("Setup Complete")
                    If lbcloseFirst.Items.Count > 0 Then
                        Dim wClose As New frmClosePrograms
                        For Each lbItem As String In lbcloseFirst.Items
                            wClose.lbItems.Items.Add(lbItem)
                        Next
                        wClose.Show()
                        Do
                            If wClose.Canceld Then
                                modMAIN.DoUninst()
                                End
                            End If
                            If wClose.Retry Then GoTo Check
                            Application.DoEvents()
                            Threading.Thread.Sleep(0)
                        Loop
                    End If

                    BlockInput(True)
                    Dim Fname As String = _ClientFolder & "\" & Mid(MpichUrl, MpichUrl.LastIndexOf("/") + 2)
                    Dim fProcces As New Process
                    With fProcces.StartInfo
                        .FileName = Fname
                        .WorkingDirectory = ClientFolder
                        .UseShellExecute = True
                        '.RedirectStandardInput = True
                    End With
                    fProcces.Start()
                    WaitMS(1000)


                    Do
                        hUninstall = FindWindow("#32770", "Setup V2.31")
                        hWelcome = FindWindow("#32770", "Welcome")
                        WaitMS(50)
                    Loop While hUninstall = 0 And hWelcome = 0
                    If hUninstall <> 0 Then
Step1:
                        SetForegroundWindow(hUninstall)
                        WaitMS(1)
                        If GetForegroundWindow = hUninstall Then
                            SendEnter()
                        Else
                            GoTo Step1
                        End If
                        Do
                            hUninstall = 0
                            WaitMS(50)
                            hUninstall = FindWindow("#32770", "Uninstall")
                        Loop While hUninstall = 0
step2:
                        If GetForegroundWindow = hUninstall Then
                            SendEnter()
                            Do
                                WaitMS(5)
                                hWelcome = FindWindow("#32770", "Welcome")
                            Loop While hWelcome = 0
                        Else
                            SetForegroundWindow(hUninstall)
                            WaitMS(5)
                            GoTo Step2
                        End If
                        GoTo Setup
                    Else
Setup:
                        If GetForegroundWindow = hWelcome Then
                            SendEnter()
                            Do
                                WaitMS(5)
                                hReadme = FindWindow("#32770", "Readme Information")
                            Loop While hReadme = 0
                        Else
                            SetForegroundWindow(hWelcome)
                            WaitMS(5)
                            GoTo Setup
                        End If
Readme:
                        If GetForegroundWindow = hReadme Then
                            SendEnter()
                            Do
                                WaitMS(5)
                                hDprofile = FindWindow("#32770", "Destination Profile Selection")
                            Loop While hDprofile = 0
                        Else
                            SetForegroundWindow(hReadme)
                            WaitMS(5)
                            GoTo Readme
                        End If
Dprofile:
                        If GetForegroundWindow = hDprofile Then
                            SendEnter()
                            Do
                                WaitMS(5)
                                hDestination = FindWindow("#32770", "Choose Destination Directory")
                            Loop While hDestination = 0
                        Else
                            SetForegroundWindow(hDprofile)
                            WaitMS(5)
                            GoTo Dprofile
                        End If
Destination:
                        If GetForegroundWindow = hDestination Then
                            SendEnter()
                            Do
                                WaitMS(5)
                                hStartCopy = FindWindow("#32770", "Start Copying Files")
                            Loop While hStartCopy = 0
                        Else
                            SetForegroundWindow(hDestination)
                            WaitMS(5)
                            GoTo Destination
                        End If
StartCopy:
                        If GetForegroundWindow = hStartCopy Then
                            SendEnter()
                            Do
                                WaitMS(5)
                                hComplete = FindWindow("#32770", "Setup Complete")
                            Loop While hComplete = 0
                        Else
                            SetForegroundWindow(hStartCopy)
                            WaitMS(5)
                            GoTo StartCopy
                        End If
SetupComplete:
                        If GetForegroundWindow = hComplete Then
                            SendEnter()
                            While Not fProcces.HasExited
                                Application.DoEvents()
                            End While
                        Else
                            SetForegroundWindow(hComplete)
                            WaitMS(5)
                            GoTo SetupComplete
                        End If
                    End If
                    BlockInput(False)



                    Dim mPath As String = vbNullString
                    Dim mFolder As String = vbNullString
                    Dim bF As Boolean = False
                    Try
                        Dim rKey As Microsoft.Win32.RegistryKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey("Software\Stanford University\Folding@Home Windows SMP Client")
                        mFolder = rKey.GetValue("Last InstPath").ToString.TrimEnd("\")
                        If My.Computer.FileSystem.FileExists(mFolder & "\Install.bat") Then
                            bF = True
                        End If
                    Catch ex As Exception

                    End Try

                    If Not bF Then
                        MsgBox("Mpich location could not be found, assuming bad install." & vbNewLine & vbNewLine & "Setup will try to revert all changes...", MsgBoxStyle.MsgBoxSetForeground)
                        DoUninst()
                        End
                    End If

                    Dim pShell As New Process
                    With pShell.StartInfo
                        .FileName = "cmd.exe"
                        .Arguments = "/c Install.bat"
                        .WorkingDirectory = mFolder
                        .UseShellExecute = False
                        .RedirectStandardInput = True
                        .RedirectStandardOutput = True
                    End With
                    pShell.Start()

                    WaitMS(1000)
                    Dim pWrite As StreamWriter = pShell.StandardInput
                    pWrite.WriteLine(vbNullString)
                    pWrite.WriteLine(hwInfo.AccPassword)
                    pWrite.WriteLine(hwInfo.AccPassword)
                    While Not pShell.HasExited
                        Dim dEnd As DateTime = DateTime.Now.AddSeconds(2)
                        While DateTime.Now < dEnd
                            Application.DoEvents()
                        End While
                        pWrite.WriteLine("fake") ' if something goes wrong with password it will use the fake, on which foo will not work 
                    End While

                    _boolIsInstalled = False
                    pShell = New Process
                    With pShell.StartInfo
                        .FileName = "cmd.exe"
                        .Arguments = "/c mpiexec -np 2 foo"
                        .WorkingDirectory = mFolder
                        .RedirectStandardOutput = True
                        .CreateNoWindow = True
                        .UseShellExecute = False
                    End With
                    pShell.Start()
                    Dim sRead As StreamReader = pShell.StandardOutput
                    Dim aText As String = sRead.ReadToEnd
                    pShell.WaitForExit()
                    If aText.ToUpper.Contains("If you see this twice, mpi is working".ToUpper & vbNewLine & "If you see this twice, mpi is working".ToUpper) Then
                        _boolIsInstalled = True
                    End If

                    If Not _boolIsInstalled Then
                        MsgBox("Foo returned wrong answer, assuming bad install." & vbNewLine & vbNewLine & "Setup will try to revert all changes, gkWare does not allow silent removals so the uninstaller when appliable will be launched.", MsgBoxStyle.MsgBoxSetForeground)
                        DoUninst()
                        End
                    End If
                    'copy exe to download clients
                    'problem with folder structure
                    Dim smpVersion As String = Mid(MpichUrl, MpichUrl.LastIndexOf("/") + 2).Replace(".exe", "")
                    Dim smpPath As String = _ClientFolder & "\" & smpVersion
                    Dim smpNexe As String = smpPath & "\" & smpEXE
                    My.Computer.FileSystem.CreateDirectory(smpPath)
                    My.Computer.FileSystem.CopyDirectory(mFolder, smpPath, True)
                    Return True
                Catch ex As Exception
                    Return False
                End Try
            End Function
            Private Sub SendEnter()
                keybd_event(VK_RETURN, 0, 0, 0)
                keybd_event(VK_RETURN, 0, KEYEVENTF_KEYUP, 0)
            End Sub
            Private Function initialDEINO() As Boolean
                Try
                    'Check for installed already
                    Dim scServices() As ServiceController, _boolIsInstalled As Boolean = False
                    scServices = ServiceController.GetServices()
                    For Each sService In scServices
                        If sService.ServiceName.ToUpper.Contains("DEINOMPI PROCESS MANAGER") Or sService.DisplayName.ToUpper.Contains("DEINOMPI PROCESS MANAGER") Then
                            If sService.Status = ServiceControllerStatus.Running Then
                                Return True
                            End If
                        End If
                    Next

                    Dim Fname As String = Application.StartupPath & "\" & Mid(DeinoUrl, DeinoUrl.LastIndexOf("/") + 2)
                    Dim fPath As String = ClientFolder & "\" & Mid(DeinoUrl, DeinoUrl.LastIndexOf("/") + 2).Replace(".zip", "")
                    If Not My.Computer.FileSystem.DirectoryExists(fPath) Then My.Computer.FileSystem.CreateDirectory(fPath)
                    unzip(Fname, fPath, True)
                    If Right(fPath, 1) = "\" Then fPath = fPath.TrimEnd("\")
                    If Not My.Computer.FileSystem.FileExists(fPath & "\DeinoMPI.msi") Then
                        MsgBox("Can't continue Deino installation because required files where not found!" & vbNewLine & "maxFAH will attempt to remove all files..", MsgBoxStyle.MsgBoxSetForeground)
                        DoUninst()
                        End
                    Else
                        Dim pD As New Process
                        With pD.StartInfo
                            .FileName = fPath & "\DeinoMPI.msi"
                            .WorkingDirectory = Mid(.FileName, 1, .FileName.LastIndexOf("\"))
                            .Arguments = "/passive"
                        End With
                        pD.Start()
                        pD.WaitForExit()
                    End If

                    Dim Pshell As New Process
                    With Pshell.StartInfo
                        .FileName = fPath & "\create_credential_store.exe"
                        .WorkingDirectory = Mid(.FileName, 1, .FileName.LastIndexOf("\"))
                        .UseShellExecute = True
                        .WindowStyle = ProcessWindowStyle.Maximized
                    End With
                    Pshell.Start()
                    BlockInput(True)
                    WaitMS(1000)
                    Dim pCount As Integer = 0
DoAgain:
                    Try

                        While GetForegroundWindow <> Pshell.MainWindowHandle
                            SetForegroundWindow(Pshell.MainWindowHandle)
                            Application.DoEvents()
                        End While
                        'create 
                        keybd_event(VK_RETURN, 0, 0, 0)
                        keybd_event(VK_RETURN, 0, KEYEVENTF_KEYUP, 0)
                        'passkey
                        WaitMS(50)
                        While GetForegroundWindow <> Pshell.MainWindowHandle
                            SetForegroundWindow(Pshell.MainWindowHandle)
                            Application.DoEvents()
                        End While
                        keybd_event(VK_RETURN, 0, 0, 0)
                        keybd_event(VK_RETURN, 0, KEYEVENTF_KEYUP, 0)
                        WaitMS(50)
                        While GetForegroundWindow <> Pshell.MainWindowHandle
                            SetForegroundWindow(Pshell.MainWindowHandle)
                            Application.DoEvents()
                        End While
                        SendKeys.SendWait("yes")
                        WaitMS(50)
                        While GetForegroundWindow <> Pshell.MainWindowHandle
                            SetForegroundWindow(Pshell.MainWindowHandle)
                            Application.DoEvents()
                        End While
                        keybd_event(VK_RETURN, 0, 0, 0)
                        keybd_event(VK_RETURN, 0, KEYEVENTF_KEYUP, 0)
                        'Enter for protected
                        WaitMS(50)
                        While GetForegroundWindow <> Pshell.MainWindowHandle
                            SetForegroundWindow(Pshell.MainWindowHandle)
                            Application.DoEvents()
                        End While
                        keybd_event(VK_RETURN, 0, 0, 0)
                        keybd_event(VK_RETURN, 0, KEYEVENTF_KEYUP, 0)
                        'Read screen output?
                        WaitMS(1000)
                        While GetForegroundWindow <> Pshell.MainWindowHandle
                            SetForegroundWindow(Pshell.MainWindowHandle)
                            Application.DoEvents()
                        End While
                        If hwInfo.HasRemovable Then
                            SendKeys.SendWait("2")
                        Else
                            SendKeys.SendWait("1")
                        End If
                        WaitMS(50)
                        While GetForegroundWindow <> Pshell.MainWindowHandle
                            SetForegroundWindow(Pshell.MainWindowHandle)
                            Application.DoEvents()
                        End While
                        keybd_event(VK_RETURN, 0, 0, 0)
                        keybd_event(VK_RETURN, 0, KEYEVENTF_KEYUP, 0)
                        WaitMS(1500)
                        If Pshell.HasExited Then
                            BlockInput(False)
                            'assume it went right
                        Else
                            Pshell.Kill()
                            While Not Pshell.HasExited
                                WaitMS(5)
                            End While
                            pCount += 1
                            If pCount >= 6 Then
                                BlockInput(False)
                                MsgBox("Could not create credential store!")
                                DoUninst()
                                End
                            End If
                            Pshell = New Process
                            With Pshell.StartInfo
                                .FileName = fPath & "\create_credential_store.exe"
                                .WorkingDirectory = Mid(.FileName, 1, .FileName.LastIndexOf("\"))
                            End With
                            Pshell.Start()
                            WaitMS(1500)
                            GoTo DoAgain
                        End If


                        Pshell = New Process
                        Dim aString As String = "/add " & hwInfo.CurrentUser & "  " & hwInfo.AccPassword
                        With Pshell.StartInfo
                            .FileName = fPath & "\manage_credentials.exe"
                            .Arguments = aString
                        End With
                        Pshell.Start()
                        Pshell.WaitForExit()

                        Dim bSer As Boolean = False
                        For Each sSer As ServiceController In ServiceController.GetServices
                            If sSer.DisplayName.ToUpper = "DEINOPM" Or sSer.DisplayName.ToUpper = "DEINOMPI PROCCESS MANAGER" Then
                                bSer = True
                                sSer.Start()
                                sSer.WaitForStatus(ServiceControllerStatus.Running, System.TimeSpan.FromSeconds(10))
                                If sSer.Status <> ServiceControllerStatus.Running Then
                                    MsgBox("The DeinoPM service could no be started!")
                                    DoUninst()
                                    End
                                End If
                            End If
                        Next




                        'check for service
                        _boolIsInstalled = False
                        Pshell = New Process
                        With Pshell.StartInfo
                            .FileName = "cmd.exe"
                            .Arguments = "/c mpiexec -np 2 foo"
                            .WorkingDirectory = fPath
                            .RedirectStandardOutput = True
                            .CreateNoWindow = True
                            .UseShellExecute = False
                        End With
                        Pshell.Start()
                        Dim sRead As StreamReader = Pshell.StandardOutput
                        Dim aText As String = sRead.ReadToEnd
                        If aText.ToUpper.Contains("If you see this twice, mpi is working".ToUpper & vbNewLine & "If you see this twice, mpi is working".ToUpper) Then
                            _boolIsInstalled = True
                        End If
                        If Not Pshell.HasExited Then Pshell.Kill()

                        If Not _boolIsInstalled Then
                            MsgBox("Foo returned wrong answer, assuming bad install." & vbNewLine & vbNewLine & "Setup will try to revert all changes, except the install of Mpich which can be done if needed through add/remove programs as usual", MsgBoxStyle.MsgBoxSetForeground)
                            DoUninst()
                            End
                        End If
                        'copy exe to download clients
                        Dim smpVersion As String = ClientFolder & "\" & Mid(DeinoUrl, DeinoUrl.LastIndexOf("/") + 2).Replace(".zip", "") & "\" & smpEXE
                        Dim smpPath As String = smpVersion.Replace(smpEXE, "")
                        My.Computer.FileSystem.CreateDirectory(smpPath)
                        If Not My.Computer.FileSystem.FileExists(smpVersion) Then My.Computer.FileSystem.CopyFile(fPath & smpEXE, smpVersion)
                        Return True
                    Catch ex As Exception
                        MsgBox("Deino configuration has returned an unexpected error, trying to revert all changes.")
                        DoUninst()
                        End
                    End Try
                Catch
                    MsgBox("Deino configuration has returned an unexpected error, trying to revert all changes.")
                    DoUninst()
                    End
                End Try
            End Function
            Private Function GpuVista() As Boolean
                Try
                    Dim Fname As String = ClientFolder & "\" & Mid(ClientInfo(eClient.GVA).Url, (ClientInfo(eClient.GVA).Url).LastIndexOf("/") + 2)
                    Dim fDir As String = ClientFolder & "\" & Mid(ClientInfo(eClient.GVA).Url, ClientInfo(eClient.GVA).Url.LastIndexOf("/") + 2).Replace(".zip", "")
                    If My.Computer.FileSystem.FileExists(fDir & "\" & gpuEXE) Then Return True
                    My.Computer.FileSystem.CreateDirectory(fDir)
                    unzip(Fname, fDir, True)
                    Return True
                Catch ex As Exception
                    DoUninst()
                    MsgBox(ex.Message)
                    Return False
                End Try
            End Function
            Private Function GpuXP() As Boolean
                Try
                    Dim Fname As String = ClientFolder & "\" & Mid(ClientInfo(eClient.GXA).Url, (ClientInfo(eClient.GXA).Url).LastIndexOf("/") + 2)
                    Dim fDir As String = ClientFolder & "\" & Mid(ClientInfo(eClient.GXA).Url, ClientInfo(eClient.GXA).Url.LastIndexOf("/") + 2).Replace(".zip", "")
                    If My.Computer.FileSystem.FileExists(fDir & "\" & gpuEXE) Then Return True
                    My.Computer.FileSystem.CreateDirectory(fDir)
                    unzip(Fname, fDir, True)
                    Return True
                Catch ex As Exception
                    MsgBox(ex.Message)
                    DoUninst()
                    Return False
                End Try
            End Function
            Private Function Uniprocessor() As Boolean
                Try
                    Dim fName As String = ClientFolder & "\" & Mid(ClientInfo(eClient.CPU).Url, (ClientInfo(eClient.CPU).Url).LastIndexOf("/") + 2)
                    Dim fDir As String = ClientFolder & "\" & Mid(ClientInfo(eClient.CPU).Url, (ClientInfo(eClient.CPU).Url).LastIndexOf("/") + 2).Replace(".zip", "")
                    If My.Computer.FileSystem.FileExists(fDir & "\" & fName) Then Return True
                    My.Computer.FileSystem.CreateDirectory(fDir)
                    unzip(fName, fDir, True)
                    Return True
                Catch ex As Exception
                    MsgBox("Error while unzipping Uniprocessor package" & vbNewLine & ex.Message)
                    DoUninst()
                    Return False
                End Try
            End Function
            Shared MpichDone As Boolean = False
            Shared DeinoDone As Boolean = False
            Shared GVistaDone As Boolean = False
            Shared GXpDone As Boolean = False
            Shared cMpich_Count As Integer = 1
            Shared cDeino_Count As Integer = 1
            Private _InstalledClients As String
            Public Function CreateRoot(ByVal InstallLocation As String) As Boolean
                Try
                    _RootFolder = InstallLocation
                    _ClientFolder = _RootFolder & "\Data\Downloaded clients"
                    _InstalledClients = _RootFolder & "\Data\Clients"
                    My.Computer.FileSystem.CreateDirectory(_RootFolder)
                    My.Computer.FileSystem.CreateDirectory(_ClientFolder)
                    My.Computer.FileSystem.CreateDirectory(_InstalledClients)
                    SetLocations(_RootFolder)
                    Return True
                Catch ex As Exception
                    Return False
                End Try
            End Function
            Public Function DeleteRoot(Optional ByVal DeleteAll As Boolean = False) As Boolean
                Try
                    My.Computer.FileSystem.DeleteDirectory(_RootFolder, FileIO.DeleteDirectoryOption.DeleteAllContents)
                    Return True
                Catch ex As Exception
                    Return False
                End Try
            End Function
#Region "URLs and client information"
            Public ReadOnly Property DeinoUrl() As String
                Get
                    Return formXML.txtUrlDeino.Text
                End Get
            End Property
            Public ReadOnly Property MpichUrl() As String
                Get
                    Return formXML.txtUrlMpich.Text
                End Get
            End Property
            Public ReadOnly Property DeinoFAQ() As String
                Get
                    Return formXML.txtDeinoFAQ.Text
                End Get
            End Property
            Public ReadOnly Property DeinoGuide() As String
                Get
                    Return formXML.txtDeinoGuide.Text
                End Get
            End Property
            Public ReadOnly Property MpichFAQ() As String
                Get
                    Return formXML.txtMpichFAQ.Text
                End Get
            End Property
            Public ReadOnly Property MpichGuide() As String
                Get
                    Return formXML.txtMpichGuide.Text
                End Get
            End Property
            Public ReadOnly Property BetaExa() As String
                Get
                    Return formXML.txtSmpBetaClient.Text
                End Get
            End Property
            Public ReadOnly Property BetaThread() As String
                Get
                    Return formXML.txtSmpBetaThread.Text
                End Get
            End Property
            Public Structure sClientInfo
                Public Url As String
                Public Faq As String
                Public Guide As String
            End Structure
            Public ReadOnly Property ClientInfo(ByVal ClientType As eClient) As sClientInfo
                Get
                    Dim nIngfo As New sClientInfo
                    With nIngfo
                        Select Case ClientType
                            Case eClient.CPU
                                .Url = formXML.txtCpuURL.Text
                                .Faq = formXML.txtCpuInstallation.Text
                                .Guide = formXML.txtCpuGuide.Text
                            Case eClient.GVA
                                .Url = formXML.txtGpu2VistaUrl.Text
                                .Guide = formXML.txtGpu2VistaGuide.Text
                                .Faq = formXML.txtGpu2VistaAtiFAQ.Text
                            Case eClient.GVN
                                .Url = formXML.txtGpu2VistaUrl.Text
                                .Guide = formXML.txtGpu2VistaGuide.Text
                                .Faq = formXML.txtGpu2VistaNvidiaFAQ.Text
                            Case eClient.GXA
                                .Url = formXML.txtGpu2XP03Url.Text
                                .Guide = formXML.txtGpu2XP03Guide.Text
                                .Faq = formXML.txtGpu2XP03AtiFAQ.Text
                            Case eClient.GXN
                                .Url = formXML.txtGpu2XP03Url.Text
                                .Guide = formXML.txtGpu2XP03Guide.Text
                                .Faq = formXML.txtGpu2XP03NvidiaFAQ.Text
                            Case eClient.SVD
                                .Url = formXML.txtUrlDeino.Text
                                .Guide = formXML.txtDeinoGuide.Text
                                .Faq = formXML.txtDeinoFAQ.Text
                            Case eClient.SXD
                                .Url = formXML.txtUrlDeino.Text
                                .Guide = formXML.txtDeinoGuide.Text
                                .Faq = formXML.txtDeinoFAQ.Text
                            Case eClient.SVM
                                .Url = formXML.txtUrlMpich.Text
                                .Faq = formXML.txtMpichFAQ.Text
                                .Guide = formXML.txtMpichGuide.Text
                            Case eClient.SXM
                                .Url = formXML.txtUrlMpich.Text
                                .Faq = formXML.txtMpichFAQ.Text
                                .Guide = formXML.txtMpichGuide.Text
                        End Select
                    End With
                    Return nIngfo
                End Get
            End Property
#End Region
            Public Structure InstalledGPU
                Dim DeviceID As String
                Dim DeviceName As String
                Dim AdapterRam As String
                Dim DeviceDescription As String
                Dim DriverVersion As String
                Dim InfSection As String
                Dim DriverDate As String
                Dim ResolvedBy As String
                Dim CanFold As Boolean

            End Structure
            Public Structure InstalledCPU
                Dim Name As String
                Dim Manufacturer As String
                Dim ClockSpeed As String
                Dim NumberOfCores As Int16
                Dim NumberOfLogicalCpus As Int16
                Public ReadOnly Property HasHT() As Boolean
                    Get
                        If NumberOfLogicalCpus <> NumberOfCores Then
                            Return True
                        Else
                            Return False
                        End If
                    End Get
                End Property
            End Structure
            Public Function SaveXML(ByVal Location As String, ByVal frmX As frmXmlCreator) As Boolean
                Try
                    Dim xWriter As XmlWriter
                    xWriter = XmlWriter.Create(Location)
                    With xWriter
                        .WriteStartElement("maxFAH_script.xml")
                        .WriteStartElement("SMP")
                        .WriteStartElement("Deino")
                        .WriteElementString("DownloadURL", frmX.txtUrlDeino.Text)
                        .WriteElementString("Faq", frmX.txtDeinoFAQ.Text)
                        .WriteElementString("Guide", frmX.txtDeinoGuide.Text)
                        .WriteEndElement()
                        .WriteStartElement("Mpich")
                        .WriteElementString("DownloadURL", frmX.txtUrlMpich.Text)
                        .WriteElementString("Faq", frmX.txtMpichFAQ.Text)
                        .WriteElementString("Guide", frmX.txtMpichGuide.Text)
                        .WriteEndElement()
                        .WriteStartElement("SmpBeta")
                        .WriteElementString("BetaExe", frmX.txtSmpBetaClient.Text)
                        .WriteElementString("BetaVersion", frmX.txtSmpBetaVersion.Text)
                        .WriteElementString("threadBetaExe", frmX.txtSmpBetaThread.Text)
                        .WriteEndElement()
                        .WriteEndElement()
                        .WriteStartElement("GPU2")
                        .WriteStartElement("Gpu2XP03")
                        .WriteElementString("DownloadURL", frmX.txtGpu2XP03Url.Text)
                        .WriteElementString("FaqNvidia", frmX.txtGpu2XP03NvidiaFAQ.Text)
                        .WriteElementString("FaqAti", frmX.txtGpu2XP03AtiFAQ.Text)
                        .WriteElementString("Guide", frmX.txtGpu2XP03Guide.Text)
                        .WriteElementString("BetaExe", frmX.txtGpuXP03BetaClient.Text)
                        .WriteElementString("BetaVersion", frmX.txtGpuXP03BetaVersion.Text)
                        .WriteElementString("BetaThread", frmX.txtGpuXP03BetaThread.Text)
                        .WriteEndElement()
                        .WriteStartElement("Gpu2Vista")
                        .WriteElementString("DownloadURL", frmX.txtGpu2VistaUrl.Text)
                        .WriteElementString("FaqNvidia", frmX.txtGpu2VistaNvidiaFAQ.Text)
                        .WriteElementString("FaqAti", frmX.txtGpu2VistaAtiFAQ.Text)
                        .WriteElementString("Guide", frmX.txtGpu2VistaGuide.Text)
                        .WriteElementString("BetaExe", frmX.txtGpuVistaBetaClient.Text)
                        .WriteElementString("BetaVersion", frmX.txtGpuVistaBetaVersion.Text)
                        .WriteElementString("BetaThread", frmX.txtGpuVistaBetaThread.Text)
                        .WriteEndElement()
                        .WriteEndElement()
                        .WriteStartElement("Cpu")
                        .WriteElementString("DownloadURL", frmX.txtCpuURL.Text)
                        .WriteElementString("Installation", frmX.txtCpuInstallation.Text)
                        .WriteElementString("Guide", frmX.txtCpuGuide.Text)
                        .WriteEndElement()
                        Return Cfg.CfgManager.PrefferedSettings.WriteToXML(xWriter, frmX)
                    End With
                Catch ex As Exception
                    Return False
                End Try
            End Function
            Public Function LoadLocalXML(ByVal FileName As String) As Boolean
                'On Error Resume Next
                If My.Computer.FileSystem.FileExists(FileName) Then
                    Dim xReader As XmlReader = XmlReader.Create(FileName)
                    With xReader
                        .ReadStartElement() 'maxfah
                        .ReadStartElement() 'smp
                        .ReadStartElement() 'deino 
                        formXML.txtUrlDeino.Text = .ReadElementString("DownloadURL")
                        formXML.txtDeinoFAQ.Text = .ReadElementString("Faq")
                        formXML.txtDeinoGuide.Text = .ReadElementString("Guide")
                        .ReadEndElement() 'Deino
                        .ReadStartElement() 'mpich
                        formXML.txtUrlMpich.Text = .ReadElementString("DownloadURL")
                        formXML.txtMpichFAQ.Text = .ReadElementString("Faq")
                        formXML.txtMpichGuide.Text = .ReadElementString("Guide")
                        .ReadEndElement() 'Mpich
                        .ReadStartElement() 'Beta
                        formXML.txtSmpBetaClient.Text = .ReadElementString("BetaExe")
                        formXML.txtSmpBetaVersion.Text = .ReadElementString("BetaVersion")
                        formXML.txtSmpBetaThread.Text = .ReadElementString("threadBetaExe")
                        .ReadEndElement() 'Beta
                        .ReadEndElement() 'Smp
                        .ReadStartElement() 'GPU
                        .ReadStartElement() 'Gx
                        formXML.txtGpu2XP03Url.Text = .ReadElementString("DownloadURL")
                        formXML.txtGpu2XP03NvidiaFAQ.Text = .ReadElementString("FaqNvidia")
                        formXML.txtGpu2XP03AtiFAQ.Text = .ReadElementString("FaqAti")
                        formXML.txtGpu2XP03Guide.Text = .ReadElementString("Guide")
                        formXML.txtGpuXP03BetaClient.Text = .ReadElementString("BetaExe")
                        formXML.txtGpuXP03BetaVersion.Text = .ReadElementString("BetaVersion")
                        formXML.txtGpuXP03BetaThread.Text = .ReadElementString("BetaThread")
                        .ReadEndElement() ' GX
                        .ReadStartElement() 'GV
                        formXML.txtGpu2VistaUrl.Text = .ReadElementString("DownloadURL")
                        formXML.txtGpu2VistaNvidiaFAQ.Text = .ReadElementString("FaqNvidia")
                        formXML.txtGpu2VistaAtiFAQ.Text = .ReadElementString("FaqAti")
                        formXML.txtGpu2VistaGuide.Text = .ReadElementString("Guide")
                        formXML.txtGpuVistaBetaClient.Text = .ReadElementString("BetaExe")
                        formXML.txtGpuVistaBetaVersion.Text = .ReadElementString("BetaVersion")
                        formXML.txtGpuVistaBetaThread.Text = .ReadElementString("BetaThread")
                        .ReadEndElement() 'GV
                        .ReadEndElement() 'GPU
                        .ReadStartElement() 'Cpu
                        formXML.txtCpuURL.Text = .ReadElementString("DownloadURL")
                        formXML.txtCpuInstallation.Text = .ReadElementString("Installation")
                        formXML.txtCpuGuide.Text = .ReadElementString("Guide")
                        .ReadEndElement()
                        '.ReadEndElement()
                    End With
                    Return Cfg.CfgManager.PrefferedSettings.ReadFromXML(xReader)
                Else
                    Return False
                End If
            End Function
            Public Function LoadWebXML(ByVal Location As String) As Boolean
                _colCpuClients = New Collection
                _colGpuClients = New Collection
                Try
                    Try
                        If Not My.Computer.Network.Ping("www.mtm78.nl") Then Return False
                    Catch ex As Exception
                        LogWindow.WriteError("LoadWebxml, ping www.mtm78.nl", Err)
                        Return False
                    End Try
                    Dim xSettings As XmlReaderSettings = New XmlReaderSettings()
                    xSettings.IgnoreComments = True
                    xSettings.IgnoreProcessingInstructions = True
                    xSettings.IgnoreWhitespace = True
                    Dim xResolver As XmlUrlResolver = New XmlUrlResolver()
                    xResolver.Credentials = System.Net.CredentialCache.DefaultCredentials
                    ' Set the reader settings object to use the resolver.
                    xSettings.XmlResolver = xResolver
                    Dim xReader As XmlReader = XmlReader.Create(Location, xSettings)
                    With xReader
                        .ReadStartElement() 'maxfah
                        .ReadStartElement() 'smp
                        .ReadStartElement() 'deino 
                        formXML.txtUrlDeino.Text = .ReadElementString("DownloadURL")
                        formXML.txtDeinoFAQ.Text = .ReadElementString("Faq")
                        formXML.txtDeinoGuide.Text = .ReadElementString("Guide")
                        .ReadEndElement() 'Deino
                        .ReadStartElement() 'mpich
                        formXML.txtUrlMpich.Text = .ReadElementString("DownloadURL")
                        formXML.txtMpichFAQ.Text = .ReadElementString("Faq")
                        formXML.txtMpichGuide.Text = .ReadElementString("Guide")
                        .ReadEndElement() 'Mpich
                        .ReadStartElement() 'Beta
                        formXML.txtSmpBetaClient.Text = .ReadElementString("BetaExe")
                        formXML.txtSmpBetaVersion.Text = .ReadElementString("BetaVersion")
                        formXML.txtSmpBetaThread.Text = .ReadElementString("threadBetaExe")
                        .ReadEndElement() 'Beta
                        .ReadEndElement() 'Smp
                        .ReadStartElement() 'GPU
                        .ReadStartElement() 'Gx
                        formXML.txtGpu2XP03Url.Text = .ReadElementString("DownloadURL")
                        formXML.txtGpu2XP03NvidiaFAQ.Text = .ReadElementString("FaqNvidia")
                        formXML.txtGpu2XP03AtiFAQ.Text = .ReadElementString("FaqAti")
                        formXML.txtGpu2XP03Guide.Text = .ReadElementString("Guide")
                        formXML.txtGpuXP03BetaClient.Text = .ReadElementString("BetaExe")
                        formXML.txtGpuXP03BetaVersion.Text = .ReadElementString("BetaVersion")
                        formXML.txtGpuXP03BetaThread.Text = .ReadElementString("BetaThread")
                        .ReadEndElement() ' GX
                        .ReadStartElement() 'GV
                        formXML.txtGpu2VistaUrl.Text = .ReadElementString("DownloadURL")
                        formXML.txtGpu2VistaNvidiaFAQ.Text = .ReadElementString("FaqNvidia")
                        formXML.txtGpu2VistaAtiFAQ.Text = .ReadElementString("FaqAti")
                        formXML.txtGpu2VistaGuide.Text = .ReadElementString("Guide")
                        formXML.txtGpuVistaBetaClient.Text = .ReadElementString("BetaExe")
                        formXML.txtGpuVistaBetaVersion.Text = .ReadElementString("BetaVersion")
                        formXML.txtGpuVistaBetaThread.Text = .ReadElementString("BetaThread")
                        .ReadEndElement() 'GV
                        .ReadEndElement() 'GPU
                        .ReadStartElement() 'Cpu
                        formXML.txtCpuURL.Text = .ReadElementString("DownloadURL")
                        formXML.txtCpuInstallation.Text = .ReadElementString("Installation")
                        formXML.txtCpuGuide.Text = .ReadElementString("Guide")
                        .ReadEndElement()
                        '.ReadEndElement()
                    End With
                    Return Cfg.CfgManager.PrefferedSettings.ReadFromXML(xReader)
                    xReader.Close()
                    xReader = Nothing
                Catch ex As Exception
                    Return False
                End Try
            End Function
            Private _colGpuClients As Collection, _colCpuClients As Collection
            Private _DoDropIn As Boolean, _AskDropIn As Boolean

            Public Sub Init()
                _colCpuClients = New Collection : _colGpuClients = New Collection
                _DoDropIn = False : _AskDropIn = True
            End Sub
            Public Function AddCpuClient(ByVal ClientType As eClient) As Boolean

                Try
                    Select Case ClientType
                        Case eClient.SVD
                            GoTo DoDeino
                        Case eClient.SXD
                            GoTo DoDeino
                        Case eClient.SXM
                            GoTo DoMpich
                        Case eClient.SVM
                            GoTo DoMpich
                        Case eClient.CPU
                            GoTo DoUniprocessor
                    End Select
                    Return False
DoUniprocessor:
                    Dim CpuInstLocation As String = _ClientFolder & "\" & Mid(ClientInfo(eClient.CPU).Url, ClientInfo(eClient.CPU).Url.LastIndexOf("/") + 2).Replace(".zip", "")
                    Dim CpuDestination As String = _InstalledClients & "\" & Mid(ClientInfo(eClient.CPU).Url, ClientInfo(eClient.CPU).Url.LastIndexOf("/") + 2).Replace(".zip", "") & " -Client " & (_colCpuClients.Count + 1).ToString
                    Dim CpuVersion As String = Mid(ClientInfo(eClient.CPU).Url, ClientInfo(eClient.CPU).Url.LastIndexOf("/") + 2).Replace(".zip", "")
                    My.Computer.FileSystem.CreateDirectory(CpuDestination)
                    My.Computer.FileSystem.CopyDirectory(CpuInstLocation, CpuDestination, True)
                    _colCpuClients.Add(CpuDestination)
                    Dim vSettings As New clsClientConfiguration.clsClientConfigs.sClientSettings.sClient
                    With vSettings
                        With .GuiController
                            .ClientEXE = CpuDestination & "\" & cpuEXE
                            .ClientLocation = CpuDestination
                            .ClientVersion = CpuVersion
                            .TypeOfClient = ClientType
                        End With
                    End With
                    Return Cfg.CfgManager.ClientSettings.AddClient(vSettings)
DoDeino:
                    Dim DeinoEXE As String = _ClientFolder & "\" & Mid(DeinoUrl, DeinoUrl.LastIndexOf("/") + 2).Replace(".zip", "") & "\" & smpEXE
                    Dim DeinoVersion As String = Mid(DeinoUrl, DeinoUrl.LastIndexOf("/") + 2).Replace(".zip", "")
                    Dim DeinoDestination As String = _InstalledClients & "\" & DeinoVersion & " - Client " & (_colCpuClients.Count + 1).ToString
                    My.Computer.FileSystem.CopyDirectory(Mid(DeinoEXE, 1, DeinoEXE.LastIndexOf("\")), DeinoDestination)
                    My.Computer.FileSystem.CreateDirectory(DeinoDestination)
                    _colCpuClients.Add(DeinoDestination)
                    'Configure client
                    Dim dSettings As New clsClientConfiguration.clsClientConfigs.sClientSettings.sClient
                    With dSettings
                        With .GuiController
                            .ClientEXE = DeinoDestination & "\" & smpEXE
                            .ClientLocation = DeinoDestination.Replace("\" & smpEXE, "")
                            .ClientVersion = DeinoVersion
                            .TypeOfClient = ClientType
                        End With
                    End With
                    'ask drop in exe if drop in is not same version as the current in the package

                    If formXML.txtSmpBetaClient.Text <> "" And DeinoVersion <> formXML.txtSmpBetaVersion.Text Then
                        If _AskDropIn Then
                            Dim rVal As MsgBoxResult = MsgBox("There is a beta drop in exe available for this client, do you want to use it?" & vbNewLine & _
                                                              "This will be appleid on all other smp clients as well!", vbYesNo + MsgBoxStyle.MsgBoxSetForeground)
                            If rVal = MsgBoxResult.No Then
                                _DoDropIn = False
                            Else

                                _DoDropIn = True
                            End If
                            _AskDropIn = False
                        End If
                        If _DoDropIn Then
                            Dim fDestExe As String = Mid(formXML.txtSmpBetaClient.Text, formXML.txtSmpBetaClient.Text.LastIndexOf("/") + 1).Replace("/", "")
                            formDownload.download(formXML.txtSmpBetaClient.Text, formDownload.PbarDownload, dSettings.GuiController.ClientLocation & "\" & fDestExe)
                            If formDownload.Visible Then formDownload.Hide()
                            'rename directory
                            Dim dFolder As String = "FAH" & formXML.txtSmpBetaVersion.Text & "-win32-SMP-Deino " & " - Client " & (_colCpuClients.Count).ToString
                            Try
                                My.Computer.FileSystem.RenameDirectory(dSettings.GuiController.ClientLocation, dFolder)
                                dFolder = _InstalledClients & "\" & dFolder
                                With dSettings
                                    With .GuiController
                                        .ClientEXE = dFolder & "\" & fDestExe
                                        .ClientLocation = dFolder
                                        .ClientVersion = "FAH" & formXML.txtSmpBetaVersion.Text & "-win32-SMP-Deino"
                                    End With
                                End With
                            Catch ex As Exception
                                Debug.Print(ex.Message)
                            End Try
                        End If
                    End If
                    Return Cfg.CfgManager.ClientSettings.AddClient(dSettings)
DoMpich:
                    Dim MpichEXE As String = _ClientFolder & "\" & Mid(MpichUrl, MpichUrl.LastIndexOf("/") + 2).Replace(".exe", "") & "\" & smpEXE
                    Dim MpichVersion As String = Mid(MpichUrl, MpichUrl.LastIndexOf("/") + 2).Replace(".zip", "").Replace(".exe", "")
                    Dim MpichDestination As String = _InstalledClients & "\" & MpichVersion & " -Client " & (_colCpuClients.Count + 1).ToString
                    My.Computer.FileSystem.CopyDirectory(Mid(MpichEXE, 1, MpichEXE.LastIndexOf("\")), MpichDestination)
                    _colCpuClients.Add(MpichDestination)
                    If Not My.Computer.FileSystem.FileExists(MpichDestination & "\" & smpEXE) Then My.Computer.FileSystem.CopyFile(MpichEXE, MpichDestination & "\" & smpEXE)
                    Dim mSettings As New clsClientConfiguration.clsClientConfigs.sClientSettings.sClient
                    With mSettings
                        With .GuiController
                            .ClientEXE = MpichDestination & "\" & smpEXE
                            .ClientLocation = MpichDestination.Replace("\" & smpEXE, "")
                            .ClientVersion = MpichVersion
                            .TypeOfClient = ClientType
                        End With
                    End With
                    'Ask for drop in exe
                    If formXML.txtSmpBetaClient.Text <> "" And MpichVersion <> formXML.txtSmpBetaVersion.Text Then
                        If _AskDropIn Then
                            Dim rVal As MsgBoxResult = MsgBox("There is a beta drop in exe available for this client, do you want to use it?" & vbNewLine & _
                                                              "This will be appleid on all other smp clients as well!", vbYesNo + MsgBoxStyle.MsgBoxSetForeground)
                            If rVal = MsgBoxResult.No Then
                                _DoDropIn = False
                            Else
                                _DoDropIn = True
                            End If
                            _AskDropIn = False
                        End If
                        If _DoDropIn Then
                            Dim fDestExe As String = Mid(formXML.txtSmpBetaClient.Text, formXML.txtSmpBetaClient.Text.LastIndexOf("/") + 1).Replace("/", "")
                            formDownload.download(formXML.txtSmpBetaClient.Text, formDownload.PbarDownload, mSettings.GuiController.ClientLocation & "\" & fDestExe)
                            If formDownload.Visible Then formDownload.Hide()
                            'rename directory
                            Dim dFolder As String = "FAH" & formXML.txtSmpBetaVersion.Text & "-win32-SMP-Mpich " & " - Client " & (_colCpuClients.Count).ToString
                            Try
                                My.Computer.FileSystem.RenameDirectory(mSettings.GuiController.ClientLocation, dFolder)
                                dFolder = _InstalledClients & "\" & dFolder
                                With mSettings
                                    With .GuiController
                                        .ClientEXE = dFolder & "\" & fDestExe
                                        .ClientLocation = dFolder
                                        .ClientVersion = "FAH" & formXML.txtSmpBetaVersion.Text & "-win32-SMP-Mpich"
                                    End With
                                End With
                            Catch ex As Exception
                                Debug.Print(ex.Message)
                            End Try
                        End If
                    End If
                    Return Cfg.CfgManager.ClientSettings.AddClient(mSettings)
                Catch ex As Exception
                    Return False
                End Try
            End Function
            Public Function AddGpuClient(ByVal ClientType As eClient) As Boolean
                Try
                    Select Case ClientType
                        Case eClient.GVA
                            GoTo DoVista
                        Case eClient.GVN
                            GoTo DoVista
                        Case eClient.GXA
                            GoTo DoXP03
                        Case eClient.GXN
                            GoTo DoXP03
                    End Select
                    Return False
DoVista:
                    Dim VinstLocation As String = _ClientFolder & "\" & Mid(ClientInfo(eClient.GVA).Url, ClientInfo(eClient.GVA).Url.LastIndexOf("/") + 2).Replace(".zip", "")
                    Dim VinstDestination As String = _InstalledClients & "\" & Mid(ClientInfo(eClient.GVA).Url, ClientInfo(eClient.GVA).Url.LastIndexOf("/") + 2).Replace(".zip", "") & " -Client " & (_colGpuClients.Count + 1).ToString
                    Dim VclientVersion As String = Mid(ClientInfo(eClient.GVA).Url, ClientInfo(eClient.GVA).Url.LastIndexOf("/") + 2).Replace(".zip", "")
                    My.Computer.FileSystem.CreateDirectory(VinstDestination)
                    My.Computer.FileSystem.CopyDirectory(VinstLocation, VinstDestination, True)
                    _colGpuClients.Add(VinstDestination)
                    Dim vSettings As New clsClientConfiguration.clsClientConfigs.sClientSettings.sClient
                    With vSettings
                        With .GuiController
                            .ClientEXE = VinstDestination & "\" & gpuEXE
                            .ClientLocation = VinstDestination
                            .ClientVersion = VclientVersion
                            .TypeOfClient = ClientType
                            .Ordinal = _colGpuClients.Count - 1
                        End With
                    End With
                    Return Cfg.CfgManager.ClientSettings.AddClient(vSettings)
DoXP03:
                    Dim XinstLocation As String = _ClientFolder & "\" & Mid(ClientInfo(eClient.GXA).Url, ClientInfo(eClient.GXA).Url.LastIndexOf("/") + 2).Replace(".zip", "")
                    Dim XinstDestination As String = _InstalledClients & "\" & Mid(ClientInfo(eClient.GXA).Url, ClientInfo(eClient.GXA).Url.LastIndexOf("/") + 2).Replace(".zip", "") & " -Client " & (_colGpuClients.Count + 1).ToString
                    Dim XclientVersion As String = Mid(ClientInfo(eClient.GXA).Url, ClientInfo(eClient.GXA).Url.LastIndexOf("/") + 2).Replace(".zip", "")
                    My.Computer.FileSystem.CreateDirectory(XinstDestination)
                    My.Computer.FileSystem.CopyDirectory(XinstLocation, XinstDestination, True)
                    _colGpuClients.Add(XinstDestination)
                    Dim xSettings As New clsClientConfiguration.clsClientConfigs.sClientSettings.sClient
                    With xSettings
                        With .GuiController
                            .ClientEXE = XinstDestination & "\" & gpuEXE
                            .ClientLocation = XinstDestination
                            .ClientVersion = XclientVersion
                            .TypeOfClient = ClientType
                            .Ordinal = _colGpuClients.Count - 1
                        End With
                    End With
                    Return Cfg.CfgManager.ClientSettings.AddClient(xSettings)
                Catch ex As Exception
                    Return False
                End Try
            End Function
        End Structure
#End Region

        Public PrefferedSettings As New sPerferdConfig
        Public WithEvents ClientSettings As New sClientSettings
        Public SetupManager As New sSetupManager

        Public Sub New()
            PrefferedSettings.Init()
            ClientSettings.init()
            SetupManager.Init()
            colFreeHWID.Clear() : colTakenHWID.Clear() : colClients.Clear() : colGPUID.Clear()
        End Sub
        Public Sub ClearAfterInstall()
            colFreeHWID.Clear() : colTakenHWID.Clear() : colClients.Clear() : colGPUID.Clear()
        End Sub
    End Class

#Region "Keeping settings for multi client setup"
    Public Class clsKeep
        Private Shared _bKeep As Boolean, _strName As String = "", _strTeam As String = "", _strUseProxy As String = "", _strUseProxyPassword As String = "", _strProxyName As String = "", _strProxyPort As String = "", _strProxyUsername As String = "", _strProxyPassword As String = "", _strAskNet As String = "", _strPassKey As String = ""
        Public Sub DoKeep(ByVal ConfigForm As frmConfig)
            With ConfigForm
                _strName = .txtUserName.Text
                _strTeam = .txtTeamNumber.Text
                _strPassKey = .txtPassKey.Text
                _strAskNet = .cmbAskNet.Text
                _strUseProxy = .cmbProxy.Text
                _strUseProxyPassword = .cmbProxyPassword.Text
                _strProxyName = .txtProxyName.Text
                _strProxyPort = .txtProxyPort.Text
                _strProxyUsername = .txtPusername.Text
                _strProxyPassword = .txtPpassword.Text
            End With
            _bKeep = True
        End Sub
        Public Property bKeep() As Boolean
            Get
                Try
                    Return _bKeep
                Catch ex As Exception
                    _bKeep = False
                    Return False
                End Try
            End Get
            Set(ByVal value As Boolean)
                _bKeep = False
            End Set
        End Property
        Public Sub KeptSettings(ByVal Configform As frmConfig)
            With Configform
                .txtUserName.Text = _strName
                .txtTeamNumber.Text = _strTeam
                .txtPassKey.Text = _strPassKey
                .cmbAskNet.Text = _strAskNet
                .cmbProxy.Text = _strUseProxy
                .cmbProxyPassword.Text = _strUseProxyPassword
                .txtProxyName.Text = _strProxyName
                .txtProxyPort.Text = _strProxyPort
                .txtPusername.Text = _strProxyUsername
                .txtPpassword.Text = _strProxyPassword
            End With
        End Sub
    End Class
    Public KeptSettings As New clsKeep
#End Region

    Public CfgManager As New clsClientConfigs
End Class
